From adaa05bc0e2621f9a162621eccafe1a163d08d66 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 22:02:07 +0000 Subject: [PATCH 01/23] Bump github.com/sigstore/cosign/v2 from 2.1.1 to 2.2.1 Bumps [github.com/sigstore/cosign/v2](https://github.com/sigstore/cosign) from 2.1.1 to 2.2.1. - [Release notes](https://github.com/sigstore/cosign/releases) - [Changelog](https://github.com/sigstore/cosign/blob/main/CHANGELOG.md) - [Commits](https://github.com/sigstore/cosign/compare/v2.1.1...v2.2.1) --- updated-dependencies: - dependency-name: github.com/sigstore/cosign/v2 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- go.mod | 277 +- go.sum | 709 +- .../go/compute/internal/version.go | 2 +- .../github.com/Azure/go-ansiterm/SECURITY.md | 41 + .../Azure/go-autorest/autorest/adal/token.go | 42 +- .../DataDog/appsec-internal-go/LICENSE | 200 + .../appsec-internal-go/httpsec/client_ip.go | 126 + .../appsec-internal-go/netip/ip_default.go | 32 + .../appsec-internal-go/netip/ip_go119.go | 34 + .../datadog-agent/pkg/obfuscate/LICENSE | 200 + .../datadog-agent/pkg/obfuscate/cache.go | 90 + .../pkg/obfuscate/credit_cards.go | 211 + .../datadog-agent/pkg/obfuscate/http.go | 60 + .../datadog-agent/pkg/obfuscate/json.go | 229 + .../pkg/obfuscate/json_scanner.go | 560 ++ .../datadog-agent/pkg/obfuscate/memcached.go | 19 + .../datadog-agent/pkg/obfuscate/obfuscate.go | 267 + .../datadog-agent/pkg/obfuscate/redis.go | 301 + .../pkg/obfuscate/redis_tokenizer.go | 187 + .../datadog-agent/pkg/obfuscate/sql.go | 416 + .../pkg/obfuscate/sql_tokenizer.go | 912 ++ .../pkg/remoteconfig/state/LICENSE | 200 + .../pkg/remoteconfig/state/README.md | 5 + .../pkg/remoteconfig/state/agent_config.go | 159 + .../pkg/remoteconfig/state/configs.go | 123 + .../remoteconfig/state/configs_agent_task.go | 59 + .../pkg/remoteconfig/state/configs_asm.go | 159 + .../pkg/remoteconfig/state/path.go | 100 + .../pkg/remoteconfig/state/products.go | 45 + .../pkg/remoteconfig/state/repository.go | 442 + .../pkg/remoteconfig/state/tuf.go | 233 + .../DataDog/datadog-go/v5/LICENSE.txt | 19 + .../DataDog/datadog-go/v5/statsd/README.md | 4 + .../datadog-go/v5/statsd/aggregator.go | 290 + .../DataDog/datadog-go/v5/statsd/buffer.go | 197 + .../datadog-go/v5/statsd/buffer_pool.go | 40 + .../v5/statsd/buffered_metric_context.go | 82 + .../DataDog/datadog-go/v5/statsd/container.go | 82 + .../DataDog/datadog-go/v5/statsd/event.go | 75 + .../DataDog/datadog-go/v5/statsd/fnv1a.go | 39 + .../DataDog/datadog-go/v5/statsd/format.go | 280 + .../DataDog/datadog-go/v5/statsd/metrics.go | 181 + .../DataDog/datadog-go/v5/statsd/noop.go | 106 + .../DataDog/datadog-go/v5/statsd/options.go | 348 + .../DataDog/datadog-go/v5/statsd/pipe.go | 13 + .../datadog-go/v5/statsd/pipe_windows.go | 75 + .../DataDog/datadog-go/v5/statsd/sender.go | 111 + .../datadog-go/v5/statsd/service_check.go | 57 + .../DataDog/datadog-go/v5/statsd/statsd.go | 838 ++ .../DataDog/datadog-go/v5/statsd/telemetry.go | 274 + .../DataDog/datadog-go/v5/statsd/udp.go | 34 + .../DataDog/datadog-go/v5/statsd/uds.go | 88 + .../datadog-go/v5/statsd/uds_windows.go | 14 + .../DataDog/datadog-go/v5/statsd/utils.go | 32 + .../DataDog/datadog-go/v5/statsd/worker.go | 150 + .../DataDog/go-libddwaf/.gitattributes | 3 + .../github.com/DataDog/go-libddwaf/.gitignore | 15 + vendor/github.com/DataDog/go-libddwaf/LICENSE | 200 + .../github.com/DataDog/go-libddwaf/README.md | 120 + .../DataDog/go-libddwaf/cgo_ref_pool.go | 90 + .../github.com/DataDog/go-libddwaf/context.go | 155 + .../github.com/DataDog/go-libddwaf/ctypes.go | 176 + .../github.com/DataDog/go-libddwaf/decoder.go | 73 + .../DataDog/go-libddwaf/embed_darwin_amd64.go | 13 + .../DataDog/go-libddwaf/embed_darwin_arm64.go | 13 + .../DataDog/go-libddwaf/embed_linux_amd64.go | 13 + .../DataDog/go-libddwaf/embed_linux_arm64.go | 13 + .../github.com/DataDog/go-libddwaf/encoder.go | 256 + .../github.com/DataDog/go-libddwaf/handle.go | 206 + .../go-libddwaf/internal/noopfree/noopfree.go | 15 + .../go-libddwaf/internal/noopfree/noopfree.s | 10 + .../lib/darwin-amd64/_libddwaf.dylib | Bin 0 -> 1375472 bytes .../lib/darwin-arm64/_libddwaf.dylib | Bin 0 -> 1289856 bytes .../go-libddwaf/lib/linux-amd64/libddwaf.so | Bin 0 -> 2269984 bytes .../go-libddwaf/lib/linux-arm64/libddwaf.so | Bin 0 -> 2122824 bytes .../github.com/DataDog/go-libddwaf/lib_dl.go | 88 + vendor/github.com/DataDog/go-libddwaf/safe.go | 68 + .../DataDog/go-libddwaf/symbols_linux_cgo.go | 21 + .../go-libddwaf/symbols_linux_purego.go | 15 + vendor/github.com/DataDog/go-libddwaf/waf.go | 130 + .../github.com/DataDog/go-libddwaf/waf_dl.go | 176 + .../DataDog/go-libddwaf/waf_dl_unsupported.go | 58 + .../DataDog/go-libddwaf/waf_unsupported_go.go | 17 + .../go-libddwaf/waf_unsupported_target.go | 17 + vendor/github.com/DataDog/go-tuf/LICENSE | 27 + .../DataDog/go-tuf/client/client.go | 982 ++ .../DataDog/go-tuf/client/delegations.go | 152 + .../DataDog/go-tuf/client/errors.go | 107 + .../DataDog/go-tuf/client/file_store.go | 90 + .../DataDog/go-tuf/client/local_store.go | 29 + .../DataDog/go-tuf/client/remote_store.go | 109 + .../DataDog/go-tuf/data/hex_bytes.go | 42 + .../github.com/DataDog/go-tuf/data/types.go | 348 + .../DataDog/go-tuf/internal/roles/roles.go | 48 + .../DataDog/go-tuf/internal/sets/strings.go | 24 + .../go-tuf/pkg/keys/deprecated_ecdsa.go | 101 + .../DataDog/go-tuf/pkg/keys/ecdsa.go | 173 + .../DataDog/go-tuf/pkg/keys/ed25519.go | 161 + .../DataDog/go-tuf/pkg/keys/keys.go | 82 + .../DataDog/go-tuf/pkg/keys/pkix.go | 56 + .../github.com/DataDog/go-tuf/pkg/keys/rsa.go | 162 + .../DataDog/go-tuf/pkg/targets/delegation.go | 102 + .../DataDog/go-tuf/pkg/targets/hash_bins.go | 113 + vendor/github.com/DataDog/go-tuf/util/util.go | 332 + vendor/github.com/DataDog/go-tuf/verify/db.go | 104 + .../DataDog/go-tuf/verify/errors.go | 73 + .../DataDog/go-tuf/verify/verify.go | 187 + .../DataDog/gostackparse/gostackparse.go | 11 + vendor/github.com/DataDog/sketches-go/LICENSE | 13 + .../DataDog/sketches-go/LICENSE-3rdparty.csv | 3 + vendor/github.com/DataDog/sketches-go/NOTICE | 4 + .../DataDog/sketches-go/ddsketch/ddsketch.go | 767 ++ .../sketches-go/ddsketch/encoding/encoding.go | 208 + .../sketches-go/ddsketch/encoding/flag.go | 160 + .../ddsketch/mapping/bit_operation_helper.go | 35 + .../mapping/cubically_interpolated_mapping.go | 146 + .../ddsketch/mapping/index_mapping.go | 95 + .../mapping/linearly_interpolated_mapping.go | 142 + .../ddsketch/mapping/logarithmic_mapping.go | 119 + .../ddsketch/pb/sketchpb/ddsketch.pb.go | 448 + .../sketches-go/ddsketch/stat/summary.go | 171 + .../DataDog/sketches-go/ddsketch/store/bin.go | 28 + .../ddsketch/store/buffered_paginated.go | 667 ++ .../store/collapsing_highest_dense_store.go | 188 + .../store/collapsing_lowest_dense_store.go | 207 + .../sketches-go/ddsketch/store/dense_store.go | 330 + .../sketches-go/ddsketch/store/sparse.go | 184 + .../sketches-go/ddsketch/store/store.go | 153 + .../go-crypto/openpgp/armor/armor.go | 11 +- .../go-crypto/openpgp/internal/ecc/x448.go | 4 +- .../ProtonMail/go-crypto/openpgp/keys.go | 4 +- .../go-crypto/openpgp/packet/public_key.go | 4 + .../go-crypto/openpgp/packet/signature.go | 2 +- .../openpgp/packet/symmetric_key_encrypted.go | 31 +- .../openpgp/packet/symmetrically_encrypted.go | 8 +- .../packet/symmetrically_encrypted_aead.go | 35 +- .../ProtonMail/go-crypto/openpgp/write.go | 2 +- .../darabonba-openapi/client/client.go | 107 +- .../tea-utils/service/service.go | 6 + .../alibabacloud-go/tea-xml/LICENSE | 201 + .../github.com/alibabacloud-go/tea/tea/tea.go | 83 +- .../credentials/access_key_credential.go | 9 + .../credentials/bearer_token_credential.go | 8 + .../credentials-go/credentials/credential.go | 21 +- .../credentials/credential_model.go | 50 + .../credentials/ecs_ram_role.go | 16 + .../credentials/oidc_credential.go | 25 +- .../credentials/oidc_credential_provider.go | 37 + .../credentials/profile_provider.go | 3 +- .../credentials-go/credentials/provider.go | 4 + .../credentials/provider_chain.go | 2 +- .../credentials/rsa_key_pair_credential.go | 18 + .../credentials/sts_credential.go | 10 + .../credentials/sts_role_arn_credential.go | 37 + .../credentials/uri_credential.go | 16 + .../credentials/utils/runtime.go | 1 + .../github.com/aws/aws-sdk-go-v2/CHANGELOG.md | 1614 +++ vendor/github.com/aws/aws-sdk-go-v2/Makefile | 14 +- .../aws/aws-sdk-go-v2/aws/config.go | 14 + .../aws-sdk-go-v2/aws/go_module_metadata.go | 2 +- .../aws-sdk-go-v2/aws/middleware/metadata.go | 33 +- .../aws/middleware/user_agent.go | 26 +- .../aws/protocol/eventstream/CHANGELOG.md | 20 + .../eventstream/go_module_metadata.go | 2 +- .../aws/protocol/query/object.go | 13 + .../aws-sdk-go-v2/aws/protocol/query/value.go | 9 + .../aws/retry/retryable_error.go | 16 +- .../aws/signer/internal/v4/headers.go | 1 + .../aws-sdk-go-v2/aws/signer/v4/middleware.go | 15 +- .../aws/aws-sdk-go-v2/aws/signer/v4/v4.go | 2 +- .../aws/aws-sdk-go-v2/ci-find-smithy-go.sh | 58 + .../aws/aws-sdk-go-v2/config/CHANGELOG.md | 83 + .../aws/aws-sdk-go-v2/config/config.go | 28 +- .../aws/aws-sdk-go-v2/config/env_config.go | 14 +- .../config/go_module_metadata.go | 2 +- .../aws/aws-sdk-go-v2/config/load_options.go | 41 + .../aws/aws-sdk-go-v2/config/provider.go | 37 + .../aws/aws-sdk-go-v2/config/resolve.go | 11 + .../aws/aws-sdk-go-v2/config/shared_config.go | 81 +- .../aws-sdk-go-v2/credentials/CHANGELOG.md | 68 + .../credentials/go_module_metadata.go | 2 +- .../feature/ec2/imds/CHANGELOG.md | 36 + .../feature/ec2/imds/go_module_metadata.go | 2 +- .../aws/aws-sdk-go-v2/internal/auth/scheme.go | 186 + .../internal/configsources/CHANGELOG.md | 36 + .../configsources/go_module_metadata.go | 2 +- .../internal/endpoints/awsrulesfn/arn.go | 94 + .../internal/endpoints/awsrulesfn/doc.go | 3 + .../internal/endpoints/awsrulesfn/generate.go | 7 + .../internal/endpoints/awsrulesfn/host.go | 51 + .../endpoints/awsrulesfn/partition.go | 75 + .../endpoints/awsrulesfn/partitions.go | 343 + .../endpoints/awsrulesfn/partitions.json | 213 + .../internal/endpoints/v2/CHANGELOG.md | 36 + .../endpoints/v2/go_module_metadata.go | 2 +- .../aws-sdk-go-v2/internal/ini/CHANGELOG.md | 41 + .../internal/ini/go_module_metadata.go | 2 +- .../internal/ini/literal_tokens.go | 186 +- .../internal/ini/number_helper.go | 152 - .../aws-sdk-go-v2/internal/ini/value_util.go | 161 - .../aws/aws-sdk-go-v2/internal/ini/visitor.go | 6 +- .../aws-sdk-go-v2/internal/v4a/CHANGELOG.md | 77 + .../internal/v4a/go_module_metadata.go | 2 +- .../aws-sdk-go-v2/internal/v4a/middleware.go | 27 +- .../github.com/aws/aws-sdk-go-v2/modman.toml | 2 +- .../aws-sdk-go-v2/service/ecr/CHANGELOG.md | 69 + .../aws-sdk-go-v2/service/ecr/api_client.go | 108 +- .../ecr/api_op_BatchCheckLayerAvailability.go | 146 +- .../service/ecr/api_op_BatchDeleteImage.go | 150 +- .../service/ecr/api_op_BatchGetImage.go | 146 +- ...BatchGetRepositoryScanningConfiguration.go | 142 +- .../service/ecr/api_op_CompleteLayerUpload.go | 142 +- .../ecr/api_op_CreatePullThroughCacheRule.go | 142 +- .../service/ecr/api_op_CreateRepository.go | 157 +- .../ecr/api_op_DeleteLifecyclePolicy.go | 142 +- .../ecr/api_op_DeletePullThroughCacheRule.go | 142 +- .../ecr/api_op_DeleteRegistryPolicy.go | 142 +- .../service/ecr/api_op_DeleteRepository.go | 142 +- .../ecr/api_op_DeleteRepositoryPolicy.go | 142 +- .../api_op_DescribeImageReplicationStatus.go | 142 +- .../ecr/api_op_DescribeImageScanFindings.go | 177 +- .../service/ecr/api_op_DescribeImages.go | 189 +- .../api_op_DescribePullThroughCacheRules.go | 143 +- .../service/ecr/api_op_DescribeRegistry.go | 142 +- .../ecr/api_op_DescribeRepositories.go | 175 +- .../ecr/api_op_GetAuthorizationToken.go | 145 +- .../ecr/api_op_GetDownloadUrlForLayer.go | 152 +- .../service/ecr/api_op_GetLifecyclePolicy.go | 142 +- .../ecr/api_op_GetLifecyclePolicyPreview.go | 165 +- .../service/ecr/api_op_GetRegistryPolicy.go | 142 +- ...api_op_GetRegistryScanningConfiguration.go | 142 +- .../service/ecr/api_op_GetRepositoryPolicy.go | 142 +- .../service/ecr/api_op_InitiateLayerUpload.go | 142 +- .../service/ecr/api_op_ListImages.go | 145 +- .../service/ecr/api_op_ListTagsForResource.go | 142 +- .../service/ecr/api_op_PutImage.go | 154 +- .../api_op_PutImageScanningConfiguration.go | 144 +- .../ecr/api_op_PutImageTagMutability.go | 147 +- .../service/ecr/api_op_PutLifecyclePolicy.go | 146 +- .../service/ecr/api_op_PutRegistryPolicy.go | 150 +- ...api_op_PutRegistryScanningConfiguration.go | 151 +- .../ecr/api_op_PutReplicationConfiguration.go | 147 +- .../service/ecr/api_op_SetRepositoryPolicy.go | 152 +- .../service/ecr/api_op_StartImageScan.go | 147 +- .../ecr/api_op_StartLifecyclePolicyPreview.go | 146 +- .../service/ecr/api_op_TagResource.go | 142 +- .../service/ecr/api_op_UntagResource.go | 142 +- .../service/ecr/api_op_UploadLayerPart.go | 148 +- .../service/ecr/deserializers.go | 15 + .../aws/aws-sdk-go-v2/service/ecr/doc.go | 20 +- .../aws-sdk-go-v2/service/ecr/endpoints.go | 380 +- .../aws-sdk-go-v2/service/ecr/generated.json | 2 + .../service/ecr/go_module_metadata.go | 2 +- .../ecr/internal/endpoints/endpoints.go | 56 +- .../aws-sdk-go-v2/service/ecr/types/enums.go | 20 +- .../aws-sdk-go-v2/service/ecr/types/errors.go | 29 +- .../aws-sdk-go-v2/service/ecr/types/types.go | 81 +- .../aws-sdk-go-v2/service/ecr/validators.go | 44 + .../service/ecrpublic/CHANGELOG.md | 200 + .../service/ecrpublic/api_client.go | 108 +- .../api_op_BatchCheckLayerAvailability.go | 166 +- .../ecrpublic/api_op_BatchDeleteImage.go | 164 +- .../ecrpublic/api_op_CompleteLayerUpload.go | 159 +- .../ecrpublic/api_op_CreateRepository.go | 161 +- .../ecrpublic/api_op_DeleteRepository.go | 156 +- .../api_op_DeleteRepositoryPolicy.go | 156 +- .../ecrpublic/api_op_DescribeImageTags.go | 195 +- .../ecrpublic/api_op_DescribeImages.go | 205 +- .../ecrpublic/api_op_DescribeRegistries.go | 189 +- .../ecrpublic/api_op_DescribeRepositories.go | 205 +- .../ecrpublic/api_op_GetAuthorizationToken.go | 144 +- .../api_op_GetRegistryCatalogData.go | 142 +- .../api_op_GetRepositoryCatalogData.go | 148 +- .../ecrpublic/api_op_GetRepositoryPolicy.go | 156 +- .../ecrpublic/api_op_InitiateLayerUpload.go | 161 +- .../ecrpublic/api_op_ListTagsForResource.go | 146 +- .../service/ecrpublic/api_op_PutImage.go | 172 +- .../api_op_PutRegistryCatalogData.go | 144 +- .../api_op_PutRepositoryCatalogData.go | 147 +- .../ecrpublic/api_op_SetRepositoryPolicy.go | 166 +- .../service/ecrpublic/api_op_TagResource.go | 154 +- .../service/ecrpublic/api_op_UntagResource.go | 146 +- .../ecrpublic/api_op_UploadLayerPart.go | 165 +- .../service/ecrpublic/deserializers.go | 402 +- .../aws-sdk-go-v2/service/ecrpublic/doc.go | 10 +- .../service/ecrpublic/endpoints.go | 342 +- .../service/ecrpublic/generated.json | 4 +- .../service/ecrpublic/go_module_metadata.go | 2 +- .../ecrpublic/internal/endpoints/endpoints.go | 66 +- .../service/ecrpublic/types/errors.go | 267 +- .../service/ecrpublic/types/types.go | 199 +- .../internal/accept-encoding/CHANGELOG.md | 20 + .../accept-encoding/go_module_metadata.go | 2 +- .../service/internal/checksum/CHANGELOG.md | 72 + .../internal/checksum/go_module_metadata.go | 2 +- .../internal/presigned-url/CHANGELOG.md | 36 + .../presigned-url/go_module_metadata.go | 2 +- .../service/internal/s3shared/CHANGELOG.md | 74 + .../internal/s3shared/arn/arn_member.go | 32 + .../internal/s3shared/config/config.go | 19 + .../internal/s3shared/go_module_metadata.go | 2 +- .../internal/s3shared/s3100continue.go | 54 + .../aws/aws-sdk-go-v2/service/s3/CHANGELOG.md | 152 + .../aws-sdk-go-v2/service/s3/api_client.go | 171 +- .../service/s3/api_op_AbortMultipartUpload.go | 231 +- .../s3/api_op_CompleteMultipartUpload.go | 387 +- .../service/s3/api_op_CopyObject.go | 588 +- .../service/s3/api_op_CreateBucket.go | 333 +- .../s3/api_op_CreateMultipartUpload.go | 647 +- .../service/s3/api_op_DeleteBucket.go | 177 +- ...i_op_DeleteBucketAnalyticsConfiguration.go | 198 +- .../service/s3/api_op_DeleteBucketCors.go | 180 +- .../s3/api_op_DeleteBucketEncryption.go | 194 +- ...teBucketIntelligentTieringConfiguration.go | 186 +- ...i_op_DeleteBucketInventoryConfiguration.go | 192 +- .../s3/api_op_DeleteBucketLifecycle.go | 186 +- ...api_op_DeleteBucketMetricsConfiguration.go | 202 +- .../api_op_DeleteBucketOwnershipControls.go | 181 +- .../service/s3/api_op_DeleteBucketPolicy.go | 191 +- .../s3/api_op_DeleteBucketReplication.go | 190 +- .../service/s3/api_op_DeleteBucketTagging.go | 177 +- .../service/s3/api_op_DeleteBucketWebsite.go | 180 +- .../service/s3/api_op_DeleteObject.go | 247 +- .../service/s3/api_op_DeleteObjectTagging.go | 214 +- .../service/s3/api_op_DeleteObjects.go | 248 +- .../s3/api_op_DeletePublicAccessBlock.go | 200 +- ...api_op_GetBucketAccelerateConfiguration.go | 200 +- .../service/s3/api_op_GetBucketAcl.go | 200 +- .../api_op_GetBucketAnalyticsConfiguration.go | 193 +- .../service/s3/api_op_GetBucketCors.go | 197 +- .../service/s3/api_op_GetBucketEncryption.go | 203 +- ...etBucketIntelligentTieringConfiguration.go | 186 +- .../api_op_GetBucketInventoryConfiguration.go | 196 +- .../api_op_GetBucketLifecycleConfiguration.go | 220 +- .../service/s3/api_op_GetBucketLocation.go | 212 +- .../service/s3/api_op_GetBucketLogging.go | 186 +- .../api_op_GetBucketMetricsConfiguration.go | 202 +- ...i_op_GetBucketNotificationConfiguration.go | 209 +- .../s3/api_op_GetBucketOwnershipControls.go | 187 +- .../service/s3/api_op_GetBucketPolicy.go | 202 +- .../s3/api_op_GetBucketPolicyStatus.go | 196 +- .../service/s3/api_op_GetBucketReplication.go | 195 +- .../s3/api_op_GetBucketRequestPayment.go | 177 +- .../service/s3/api_op_GetBucketTagging.go | 185 +- .../service/s3/api_op_GetBucketVersioning.go | 185 +- .../service/s3/api_op_GetBucketWebsite.go | 190 +- .../service/s3/api_op_GetObject.go | 426 +- .../service/s3/api_op_GetObjectAcl.go | 218 +- .../service/s3/api_op_GetObjectAttributes.go | 361 +- .../service/s3/api_op_GetObjectLegalHold.go | 188 +- .../s3/api_op_GetObjectLockConfiguration.go | 189 +- .../service/s3/api_op_GetObjectRetention.go | 188 +- .../service/s3/api_op_GetObjectTagging.go | 226 +- .../service/s3/api_op_GetObjectTorrent.go | 192 +- .../service/s3/api_op_GetPublicAccessBlock.go | 200 +- .../service/s3/api_op_HeadBucket.go | 246 +- .../service/s3/api_op_HeadObject.go | 488 +- ...pi_op_ListBucketAnalyticsConfigurations.go | 198 +- ...tBucketIntelligentTieringConfigurations.go | 190 +- ...pi_op_ListBucketInventoryConfigurations.go | 200 +- .../api_op_ListBucketMetricsConfigurations.go | 206 +- .../service/s3/api_op_ListBuckets.go | 157 +- .../service/s3/api_op_ListMultipartUploads.go | 303 +- .../service/s3/api_op_ListObjectVersions.go | 262 +- .../service/s3/api_op_ListObjects.go | 269 +- .../service/s3/api_op_ListObjectsV2.go | 310 +- .../service/s3/api_op_ListParts.go | 292 +- ...api_op_PutBucketAccelerateConfiguration.go | 205 +- .../service/s3/api_op_PutBucketAcl.go | 405 +- .../api_op_PutBucketAnalyticsConfiguration.go | 237 +- .../service/s3/api_op_PutBucketCors.go | 249 +- .../service/s3/api_op_PutBucketEncryption.go | 234 +- ...utBucketIntelligentTieringConfiguration.go | 223 +- .../api_op_PutBucketInventoryConfiguration.go | 245 +- .../api_op_PutBucketLifecycleConfiguration.go | 258 +- .../service/s3/api_op_PutBucketLogging.go | 233 +- .../api_op_PutBucketMetricsConfiguration.go | 228 +- ...i_op_PutBucketNotificationConfiguration.go | 215 +- .../s3/api_op_PutBucketOwnershipControls.go | 187 +- .../service/s3/api_op_PutBucketPolicy.go | 201 +- .../service/s3/api_op_PutBucketReplication.go | 249 +- .../s3/api_op_PutBucketRequestPayment.go | 196 +- .../service/s3/api_op_PutBucketTagging.go | 256 +- .../service/s3/api_op_PutBucketVersioning.go | 222 +- .../service/s3/api_op_PutBucketWebsite.go | 284 +- .../service/s3/api_op_PutObject.go | 482 +- .../service/s3/api_op_PutObjectAcl.go | 419 +- .../service/s3/api_op_PutObjectLegalHold.go | 188 +- .../s3/api_op_PutObjectLockConfiguration.go | 206 +- .../service/s3/api_op_PutObjectRetention.go | 208 +- .../service/s3/api_op_PutObjectTagging.go | 276 +- .../service/s3/api_op_PutPublicAccessBlock.go | 213 +- .../service/s3/api_op_RestoreObject.go | 532 +- .../service/s3/api_op_SelectObjectContent.go | 316 +- .../service/s3/api_op_UploadPart.go | 409 +- .../service/s3/api_op_UploadPartCopy.go | 445 +- .../s3/api_op_WriteGetObjectResponse.go | 286 +- .../aws/aws-sdk-go-v2/service/s3/bucketer.go | 15 + .../aws-sdk-go-v2/service/s3/deserializers.go | 169 + .../aws/aws-sdk-go-v2/service/s3/endpoints.go | 4181 +++++++- .../aws-sdk-go-v2/service/s3/generated.json | 4 +- .../service/s3/go_module_metadata.go | 2 +- .../service/s3/handwritten_paginators.go | 204 + .../service/s3/internal/customizations/doc.go | 1 - .../customizations/process_arn_resource.go | 4 + .../remove_bucket_middleware.go | 5 + .../customizations/s3_object_lambda.go | 4 + .../internal/customizations/signer_wrapper.go | 20 +- .../customizations/update_endpoint.go | 8 +- .../s3/internal/endpoints/endpoints.go | 125 +- .../s3/serialize_immutable_hostname_bucket.go | 72 + .../aws-sdk-go-v2/service/s3/serializers.go | 1901 ++-- .../aws-sdk-go-v2/service/s3/types/enums.go | 153 +- .../aws-sdk-go-v2/service/s3/types/errors.go | 91 +- .../aws-sdk-go-v2/service/s3/types/types.go | 2201 ++-- .../aws-sdk-go-v2/service/sso/CHANGELOG.md | 58 + .../aws-sdk-go-v2/service/sso/api_client.go | 106 +- .../service/sso/api_op_GetRoleCredentials.go | 139 +- .../service/sso/api_op_ListAccountRoles.go | 138 +- .../service/sso/api_op_ListAccounts.go | 138 +- .../service/sso/api_op_Logout.go | 139 +- .../aws-sdk-go-v2/service/sso/endpoints.go | 361 +- .../aws-sdk-go-v2/service/sso/generated.json | 4 +- .../service/sso/go_module_metadata.go | 2 +- .../sso/internal/endpoints/endpoints.go | 36 +- .../aws-sdk-go-v2/service/sso/serializers.go | 36 +- .../service/ssooidc/CHANGELOG.md | 58 + .../service/ssooidc/api_client.go | 106 +- .../service/ssooidc/api_op_CreateToken.go | 139 +- .../service/ssooidc/api_op_RegisterClient.go | 139 +- .../api_op_StartDeviceAuthorization.go | 139 +- .../service/ssooidc/endpoints.go | 361 +- .../service/ssooidc/generated.json | 4 +- .../service/ssooidc/go_module_metadata.go | 2 +- .../ssooidc/internal/endpoints/endpoints.go | 36 +- .../service/ssooidc/serializers.go | 27 +- .../aws-sdk-go-v2/service/sts/CHANGELOG.md | 54 + .../aws-sdk-go-v2/service/sts/api_client.go | 106 +- .../service/sts/api_op_AssumeRole.go | 142 +- .../service/sts/api_op_AssumeRoleWithSAML.go | 139 +- .../sts/api_op_AssumeRoleWithWebIdentity.go | 142 +- .../sts/api_op_DecodeAuthorizationMessage.go | 139 +- .../service/sts/api_op_GetAccessKeyInfo.go | 139 +- .../service/sts/api_op_GetCallerIdentity.go | 139 +- .../service/sts/api_op_GetFederationToken.go | 139 +- .../service/sts/api_op_GetSessionToken.go | 139 +- .../aws-sdk-go-v2/service/sts/endpoints.go | 838 +- .../aws-sdk-go-v2/service/sts/generated.json | 4 +- .../service/sts/go_module_metadata.go | 2 +- .../sts/internal/endpoints/endpoints.go | 5 +- .../aws-sdk-go-v2/service/sts/serializers.go | 36 + .../aws-sdk-go-v2/service/sts/types/types.go | 12 + vendor/github.com/aws/smithy-go/.gitignore | 4 + vendor/github.com/aws/smithy-go/CHANGELOG.md | 21 + vendor/github.com/aws/smithy-go/README.md | 15 + .../smithy-go/encoding/httpbinding/encode.go | 13 +- .../aws/smithy-go/endpoints/endpoint.go | 23 + .../endpoints/private/rulesfn/doc.go | 4 + .../endpoints/private/rulesfn/strings.go | 26 + .../endpoints/private/rulesfn/uri.go | 130 + .../aws/smithy-go/go_module_metadata.go | 2 +- vendor/github.com/aws/smithy-go/properties.go | 52 + .../http/middleware_header_comment.go | 81 + .../ecr-login/api/client.go | 7 +- .../ecr-login/cache/file.go | 3 +- .../buildkite/agent/v3/api/annotations.go | 4 +- .../buildkite/agent/v3/api/artifacts.go | 6 +- .../buildkite/agent/v3/api/chunks.go | 8 +- .../buildkite/agent/v3/api/client.go | 5 + .../buildkite/agent/v3/api/header_times.go | 2 +- .../github.com/buildkite/agent/v3/api/jobs.go | 41 +- .../buildkite/agent/v3/api/meta_data.go | 8 +- .../github.com/buildkite/agent/v3/api/oidc.go | 2 +- .../buildkite/agent/v3/api/pipelines.go | 4 +- .../buildkite/agent/v3/api/steps.go | 4 +- .../buildkite/agent/v3/env/environment.go | 298 + .../agent/v3/internal/ordered/map.go | 417 + .../agent/v3/internal/ordered/slice.go | 30 + .../agent/v3/internal/ordered/strings.go | 39 + .../agent/v3/internal/ordered/tuple.go | 15 + .../agent/v3/internal/ordered/unmarshal.go | 384 + .../agent/v3/internal/ordered/yaml.go | 260 + .../agent/v3/internal/pipeline/doc.go | 13 + .../agent/v3/internal/pipeline/interpolate.go | 161 + .../internal/pipeline/interpolate_matrix.go | 55 + .../agent/v3/internal/pipeline/json.go | 98 + .../agent/v3/internal/pipeline/parser.go | 32 + .../agent/v3/internal/pipeline/pipeline.go | 131 + .../internal/pipeline/pipeline_invariants.go | 82 + .../agent/v3/internal/pipeline/plugin.go | 112 + .../agent/v3/internal/pipeline/plugins.go | 106 + .../agent/v3/internal/pipeline/sign.go | 185 + .../agent/v3/internal/pipeline/step.go | 13 + .../v3/internal/pipeline/step_command.go | 125 + .../internal/pipeline/step_command_matrix.go | 365 + .../agent/v3/internal/pipeline/step_group.go | 57 + .../agent/v3/internal/pipeline/step_input.go | 34 + .../agent/v3/internal/pipeline/step_scalar.go | 41 + .../v3/internal/pipeline/step_trigger.go | 23 + .../v3/internal/pipeline/step_unknown.go | 40 + .../agent/v3/internal/pipeline/step_wait.go | 35 + .../agent/v3/internal/pipeline/steps.go | 170 + .../buildkite/agent/v3/logger/buffer.go | 14 + .../buildkite/agent/v3/logger/log.go | 6 +- .../buildkite/agent/v3/tracetools/doc.go | 5 + .../agent/v3/tracetools/propagate.go | 55 + .../buildkite/agent/v3/tracetools/span.go | 129 + .../buildkite/agent/v3/version/VERSION | 1 + .../buildkite/agent/v3/version/version.go | 81 + .../buildkite/interpolate/LICENSE.txt | 24 + .../buildkite/interpolate/README.md | 61 + .../github.com/buildkite/interpolate/env.go | 49 + .../buildkite/interpolate/interpolate.go | 212 + .../buildkite/interpolate/parser.go | 287 + .../pkg/token/token.go | 44 +- vendor/github.com/clbanning/mxj/v2/doc.go | 5 + .../github.com/clbanning/mxj/v2/leafnode.go | 2 +- vendor/github.com/clbanning/mxj/v2/readme.md | 4 +- vendor/github.com/clbanning/mxj/v2/xml.go | 38 +- vendor/github.com/clbanning/mxj/v2/xmlseq.go | 111 +- .../cloudflare/circl/ecc/goldilocks/twist.go | 2 +- .../cloudflare/circl/internal/sha3/keccakf.go | 12 +- .../cloudflare/circl/internal/sha3/sha3.go | 11 +- .../cloudflare/circl/internal/sha3/shake.go | 40 + .../cloudflare/circl/math/primes.go | 34 + .../cloudflare/circl/sign/ed25519/ed25519.go | 2 +- .../github.com/coreos/go-oidc/v3/oidc/jwks.go | 8 +- .../github.com/coreos/go-oidc/v3/oidc/oidc.go | 6 +- .../coreos/go-oidc/v3/oidc/verify.go | 4 +- .../decred/dcrd/dcrec/secp256k1/v4/LICENSE | 17 + .../decred/dcrd/dcrec/secp256k1/v4/README.md | 72 + .../secp256k1/v4/compressedbytepoints.go | 18 + .../decred/dcrd/dcrec/secp256k1/v4/curve.go | 1272 +++ .../decred/dcrd/dcrec/secp256k1/v4/doc.go | 59 + .../decred/dcrd/dcrec/secp256k1/v4/ecdh.go | 21 + .../dcrec/secp256k1/v4/ellipticadaptor.go | 255 + .../decred/dcrd/dcrec/secp256k1/v4/error.go | 67 + .../decred/dcrd/dcrec/secp256k1/v4/field.go | 1681 ++++ .../dcrec/secp256k1/v4/loadprecomputed.go | 91 + .../dcrd/dcrec/secp256k1/v4/modnscalar.go | 1101 ++ .../decred/dcrd/dcrec/secp256k1/v4/nonce.go | 263 + .../decred/dcrd/dcrec/secp256k1/v4/privkey.go | 111 + .../decred/dcrd/dcrec/secp256k1/v4/pubkey.go | 237 + vendor/github.com/digitorus/pkcs7/Makefile | 2 +- vendor/github.com/digitorus/pkcs7/ber.go | 34 +- vendor/github.com/digitorus/pkcs7/pkcs7.go | 4 +- .../digitorus/timestamp/rfc3161_struct.go | 2 +- .../digitorus/timestamp/timestamp.go | 60 +- .../distribution/reference/.gitattributes | 1 + .../distribution/reference/.gitignore | 2 + .../distribution/reference/.golangci.yml | 18 + .../distribution/reference/CODE-OF-CONDUCT.md | 5 + .../distribution/reference/CONTRIBUTING.md | 114 + .../distribution/reference/GOVERNANCE.md | 144 + .../github.com/distribution/reference/LICENSE | 202 + .../distribution/reference/MAINTAINERS | 26 + .../distribution/reference/Makefile | 25 + .../distribution/reference/README.md | 30 + .../distribution/reference/SECURITY.md | 7 + .../reference/distribution-logo.svg | 1 + .../distribution/reference/helpers.go | 2 +- .../distribution/reference/normalize.go | 131 +- .../distribution/reference/reference.go | 27 +- .../distribution/reference/regexp.go | 163 + .../github.com/distribution/reference/sort.go | 75 + .../github.com/docker/cli/cli/command/cli.go | 18 +- .../docker/cli/cli/command/events_utils.go | 14 +- .../docker/cli/cli/command/registry.go | 101 +- .../docker/cli/cli/command/streams.go | 32 - .../docker/cli/cli/config/configfile/file.go | 4 +- .../cli/cli/config/credentials/file_store.go | 3 +- .../cli/connhelper/commandconn/commandconn.go | 208 +- .../docker/cli/cli/connhelper/connhelper.go | 16 +- .../docker/cli/cli/connhelper/ssh/ssh.go | 5 +- .../docker/cli/cli/context/docker/load.go | 6 - .../docker/cli/cli/context/store/store.go | 14 - .../docker/cli/cli/flags/options.go | 2 +- .../cli/cli/flags/options_deprecated.go | 11 - .../github.com/docker/cli/cli/hints/hints.go | 18 + .../docker/cli/cli/registry/client/client.go | 10 +- .../cli/cli/registry/client/endpoint.go | 13 +- .../docker/cli/cli/registry/client/fetcher.go | 8 +- .../github.com/docker/cli/cli/streams/in.go | 27 +- .../github.com/docker/cli/cli/streams/out.go | 30 +- .../docker/cli/cli/streams/stream.go | 13 +- .../github.com/docker/cli/cli/trust/trust.go | 30 +- .../docker/cli/opts/capabilities.go | 14 +- .../docker/distribution/.golangci.yml | 10 +- .../github.com/docker/distribution/.mailmap | 3 + .../docker/distribution/BUILDING.md | 2 +- .../github.com/docker/distribution/Dockerfile | 8 +- .../github.com/docker/distribution/Makefile | 2 +- .../github.com/docker/distribution/blobs.go | 2 +- .../reference/helpers_deprecated.go | 34 + .../reference/normalize_deprecated.go | 92 + .../reference/reference_deprecated.go | 172 + .../docker/distribution/reference/regexp.go | 143 - .../reference/regexp_deprecated.go | 50 + .../distribution/reference/sort_deprecated.go | 10 + .../docker/distribution/registry.go | 2 +- .../registry/api/v2/descriptors.go | 2 +- .../distribution/registry/api/v2/urls.go | 2 +- .../registry/client/blob_writer.go | 2 + .../distribution/registry/client/errors.go | 51 +- .../registry/client/repository.go | 2 +- .../registry/storage/cache/memory/memory.go | 2 +- .../docker/distribution/vendor.conf | 3 +- .../client/client.go | 8 +- .../client/command.go | 13 +- .../credentials/credentials.go | 69 +- .../credentials/error.go | 31 +- vendor/github.com/docker/docker/AUTHORS | 18 + vendor/github.com/docker/docker/api/common.go | 2 +- .../github.com/docker/docker/api/swagger.yaml | 149 +- .../docker/docker/api/types/auth.go | 25 +- .../docker/docker/api/types/client.go | 3 +- .../docker/docker/api/types/configs.go | 4 +- .../container/change_response_deprecated.go | 6 + .../docker/api/types/container/change_type.go | 15 + .../api/types/container/change_types.go | 23 + .../api/types/container/container_changes.go | 20 - .../docker/api/types/container/deprecated.go | 16 - .../api/types/container/filesystem_change.go | 19 + .../{host_config.go => hostconfig.go} | 129 +- .../docker/docker/api/types/deprecated.go | 14 - .../docker/docker/api/types/filters/errors.go | 37 + .../docker/docker/api/types/filters/parse.go | 51 +- .../docker/docker/api/types/image/opts.go | 9 + .../docker/docker/api/types/image_summary.go | 13 +- .../docker/api/types/registry/authconfig.go | 99 + .../docker/api/types/registry/registry.go | 6 +- .../docker/docker/api/types/time/timestamp.go | 40 +- .../docker/docker/api/types/types.go | 34 +- .../docker/api/types/versions/compare.go | 8 +- .../docker/api/types/volume/deprecated.go | 11 - .../docker/docker/client/build_prune.go | 10 +- .../github.com/docker/docker/client/client.go | 53 +- .../docker/docker/client/client_unix.go | 7 +- .../docker/docker/client/client_windows.go | 3 - .../docker/docker/client/container_create.go | 6 +- .../docker/docker/client/container_diff.go | 4 +- .../docker/client/distribution_inspect.go | 8 +- .../github.com/docker/docker/client/errors.go | 25 - .../github.com/docker/docker/client/hijack.go | 13 +- .../docker/docker/client/image_create.go | 3 +- .../docker/docker/client/image_push.go | 3 +- .../docker/docker/client/image_search.go | 2 +- .../docker/docker/client/interface.go | 10 +- .../github.com/docker/docker/client/login.go | 3 +- .../github.com/docker/docker/client/ping.go | 6 +- .../docker/docker/client/plugin_install.go | 7 +- .../docker/docker/client/plugin_push.go | 4 +- .../docker/docker/client/plugin_upgrade.go | 3 +- .../docker/docker/client/request.go | 10 +- .../docker/docker/client/service_create.go | 3 +- .../docker/docker/client/service_update.go | 3 +- .../docker/docker/client/volume_list.go | 6 +- .../docker/pkg/homedir/homedir_linux.go | 9 +- .../docker/docker/pkg/ioutils/temp_unix.go | 11 - .../docker/docker/pkg/ioutils/temp_windows.go | 16 - .../docker/pkg/ioutils/tempdir_deprecated.go | 10 + .../docker/pkg/jsonmessage/jsonmessage.go | 92 +- .../docker/docker/pkg/longpath/longpath.go | 27 +- .../github.com/docker/docker/registry/auth.go | 13 +- .../docker/docker/registry/endpoint_v1.go | 8 +- .../docker/docker/registry/search.go | 139 + .../docker/docker/registry/service.go | 108 +- .../docker/docker/registry/service_v2.go | 2 +- .../docker/docker/registry/session.go | 11 +- .../github.com/dustin/go-humanize/.travis.yml | 21 + vendor/github.com/dustin/go-humanize/LICENSE | 21 + .../dustin/go-humanize/README.markdown | 124 + vendor/github.com/dustin/go-humanize/big.go | 31 + .../github.com/dustin/go-humanize/bigbytes.go | 189 + vendor/github.com/dustin/go-humanize/bytes.go | 143 + vendor/github.com/dustin/go-humanize/comma.go | 116 + .../github.com/dustin/go-humanize/commaf.go | 41 + vendor/github.com/dustin/go-humanize/ftoa.go | 49 + .../github.com/dustin/go-humanize/humanize.go | 8 + .../github.com/dustin/go-humanize/number.go | 192 + .../github.com/dustin/go-humanize/ordinals.go | 25 + vendor/github.com/dustin/go-humanize/si.go | 127 + vendor/github.com/dustin/go-humanize/times.go | 117 + .../github.com/ebitengine/purego/.gitignore | 1 + .../purego}/LICENSE | 0 vendor/github.com/ebitengine/purego/README.md | 74 + .../github.com/ebitengine/purego/abi_amd64.h | 99 + .../github.com/ebitengine/purego/abi_arm64.h | 39 + vendor/github.com/ebitengine/purego/cgo.go | 15 + .../github.com/ebitengine/purego/dlerror.go | 15 + vendor/github.com/ebitengine/purego/dlfcn.go | 94 + .../ebitengine/purego/dlfcn_darwin.go | 19 + .../ebitengine/purego/dlfcn_freebsd.go | 18 + .../ebitengine/purego/dlfcn_linux.go | 14 + .../ebitengine/purego/dlfcn_nocgo_linux.go | 19 + .../ebitengine/purego/dlfcn_stubs.s | 26 + vendor/github.com/ebitengine/purego/func.go | 305 + .../ebitengine/purego/go_runtime.go | 17 + .../purego/internal/cgo/syscall_cgo_unix.go | 58 + .../purego/internal/fakecgo/abi_amd64.h | 99 + .../purego/internal/fakecgo/abi_arm64.h | 39 + .../purego/internal/fakecgo/asm_amd64.s | 39 + .../purego/internal/fakecgo/asm_arm64.s | 36 + .../purego/internal/fakecgo/callbacks.go | 93 + .../ebitengine/purego/internal/fakecgo/doc.go | 33 + .../purego/internal/fakecgo/freebsd.go | 27 + .../internal/fakecgo/go_darwin_amd64.go | 71 + .../internal/fakecgo/go_darwin_arm64.go | 86 + .../internal/fakecgo/go_freebsd_amd64.go | 93 + .../internal/fakecgo/go_freebsd_arm64.go | 96 + .../purego/internal/fakecgo/go_libinit.go | 66 + .../purego/internal/fakecgo/go_linux_amd64.go | 93 + .../purego/internal/fakecgo/go_linux_arm64.go | 96 + .../purego/internal/fakecgo/go_setenv.go | 18 + .../purego/internal/fakecgo/go_util.go | 33 + .../purego/internal/fakecgo/iscgo.go | 19 + .../purego/internal/fakecgo/libcgo.go | 35 + .../purego/internal/fakecgo/libcgo_darwin.go | 20 + .../purego/internal/fakecgo/libcgo_freebsd.go | 14 + .../purego/internal/fakecgo/libcgo_linux.go | 14 + .../purego/internal/fakecgo/setenv.go | 19 + .../purego/internal/fakecgo/symbols.go | 184 + .../purego/internal/fakecgo/symbols_darwin.go | 27 + .../internal/fakecgo/symbols_freebsd.go | 27 + .../purego/internal/fakecgo/symbols_linux.go | 27 + .../internal/fakecgo/trampolines_amd64.s | 104 + .../internal/fakecgo/trampolines_arm64.s | 72 + .../internal/fakecgo/trampolines_stubs.s | 90 + .../purego/internal/strings/strings.go | 40 + vendor/github.com/ebitengine/purego/is_ios.go | 13 + vendor/github.com/ebitengine/purego/nocgo.go | 25 + .../github.com/ebitengine/purego/sys_amd64.s | 143 + .../github.com/ebitengine/purego/sys_arm64.s | 63 + .../ebitengine/purego/sys_unix_arm64.s | 70 + .../github.com/ebitengine/purego/syscall.go | 40 + .../ebitengine/purego/syscall_cgo_linux.go | 30 + .../ebitengine/purego/syscall_sysv.go | 214 + .../ebitengine/purego/syscall_windows.go | 45 + .../ebitengine/purego/zcallback_amd64.s | 2014 ++++ .../ebitengine/purego/zcallback_arm64.s | 4014 ++++++++ .../emicklei/go-restful/v3/CHANGES.md | 11 +- .../emicklei/go-restful/v3/README.md | 5 +- .../emicklei/go-restful/v3/route.go | 17 +- .../emicklei/go-restful/v3/route_builder.go | 45 +- vendor/github.com/fatih/color/README.md | 14 +- vendor/github.com/fatih/color/color.go | 46 +- .../github.com/fatih/color/color_windows.go | 19 + vendor/github.com/fatih/color/doc.go | 137 +- .../github.com/fsnotify/fsnotify/.cirrus.yml | 13 + .../github.com/fsnotify/fsnotify/.gitignore | 1 + .../github.com/fsnotify/fsnotify/CHANGELOG.md | 83 +- vendor/github.com/fsnotify/fsnotify/README.md | 81 +- .../fsnotify/fsnotify/backend_fen.go | 552 +- .../fsnotify/fsnotify/backend_inotify.go | 377 +- .../fsnotify/fsnotify/backend_kqueue.go | 295 +- .../fsnotify/fsnotify/backend_other.go | 205 +- .../fsnotify/fsnotify/backend_windows.go | 247 +- .../github.com/fsnotify/fsnotify/fsnotify.go | 91 +- vendor/github.com/fsnotify/fsnotify/mkdoc.zsh | 125 +- .../gabriel-vasile/mimetype/README.md | 3 - .../mimetype/internal/magic/binary.go | 38 +- .../mimetype/internal/magic/magic.go | 4 +- .../mimetype/internal/magic/text_csv.go | 18 +- .../gabriel-vasile/mimetype/mimetype.go | 3 +- .../mimetype/supported_mimes.md | 2 +- vendor/github.com/go-logr/logr/README.md | 113 +- vendor/github.com/go-logr/logr/SECURITY.md | 18 + vendor/github.com/go-logr/logr/funcr/funcr.go | 48 +- vendor/github.com/go-logr/logr/logr.go | 35 +- vendor/github.com/go-openapi/errors/api.go | 2 +- .../go-openapi/jsonpointer/pointer.go | 147 +- .../go-playground/validator/v10/Makefile | 2 +- .../go-playground/validator/v10/README.md | 140 +- .../go-playground/validator/v10/baked_in.go | 126 +- .../go-playground/validator/v10/doc.go | 26 +- .../go-playground/validator/v10/options.go | 16 + .../go-playground/validator/v10/regexes.go | 6 + .../go-playground/validator/v10/util.go | 12 +- .../go-playground/validator/v10/validator.go | 113 +- .../validator/v10/validator_instance.go | 34 +- vendor/github.com/goccy/go-json/.codecov.yml | 32 + vendor/github.com/goccy/go-json/.gitignore | 2 + vendor/github.com/goccy/go-json/.golangci.yml | 83 + vendor/github.com/goccy/go-json/CHANGELOG.md | 425 + vendor/github.com/goccy/go-json/LICENSE | 21 + vendor/github.com/goccy/go-json/Makefile | 39 + vendor/github.com/goccy/go-json/README.md | 529 + vendor/github.com/goccy/go-json/color.go | 68 + vendor/github.com/goccy/go-json/decode.go | 263 + .../goccy/go-json/docker-compose.yml | 13 + vendor/github.com/goccy/go-json/encode.go | 326 + vendor/github.com/goccy/go-json/error.go | 41 + .../internal/decoder/anonymous_field.go | 41 + .../goccy/go-json/internal/decoder/array.go | 176 + .../goccy/go-json/internal/decoder/assign.go | 438 + .../goccy/go-json/internal/decoder/bool.go | 83 + .../goccy/go-json/internal/decoder/bytes.go | 118 + .../goccy/go-json/internal/decoder/compile.go | 487 + .../internal/decoder/compile_norace.go | 29 + .../go-json/internal/decoder/compile_race.go | 37 + .../goccy/go-json/internal/decoder/context.go | 254 + .../goccy/go-json/internal/decoder/float.go | 170 + .../goccy/go-json/internal/decoder/func.go | 146 + .../goccy/go-json/internal/decoder/int.go | 246 + .../go-json/internal/decoder/interface.go | 528 + .../goccy/go-json/internal/decoder/invalid.go | 55 + .../goccy/go-json/internal/decoder/map.go | 280 + .../goccy/go-json/internal/decoder/number.go | 123 + .../goccy/go-json/internal/decoder/option.go | 17 + .../goccy/go-json/internal/decoder/path.go | 670 ++ .../goccy/go-json/internal/decoder/ptr.go | 96 + .../goccy/go-json/internal/decoder/slice.go | 380 + .../goccy/go-json/internal/decoder/stream.go | 556 ++ .../goccy/go-json/internal/decoder/string.go | 452 + .../goccy/go-json/internal/decoder/struct.go | 845 ++ .../goccy/go-json/internal/decoder/type.go | 30 + .../goccy/go-json/internal/decoder/uint.go | 194 + .../internal/decoder/unmarshal_json.go | 104 + .../internal/decoder/unmarshal_text.go | 285 + .../internal/decoder/wrapped_string.go | 73 + .../goccy/go-json/internal/encoder/code.go | 1023 ++ .../goccy/go-json/internal/encoder/compact.go | 286 + .../go-json/internal/encoder/compiler.go | 935 ++ .../internal/encoder/compiler_norace.go | 32 + .../go-json/internal/encoder/compiler_race.go | 45 + .../goccy/go-json/internal/encoder/context.go | 105 + .../go-json/internal/encoder/decode_rune.go | 126 + .../goccy/go-json/internal/encoder/encoder.go | 596 ++ .../goccy/go-json/internal/encoder/indent.go | 211 + .../goccy/go-json/internal/encoder/int.go | 152 + .../goccy/go-json/internal/encoder/map112.go | 9 + .../goccy/go-json/internal/encoder/map113.go | 9 + .../goccy/go-json/internal/encoder/opcode.go | 752 ++ .../goccy/go-json/internal/encoder/option.go | 48 + .../goccy/go-json/internal/encoder/optype.go | 932 ++ .../goccy/go-json/internal/encoder/query.go | 135 + .../goccy/go-json/internal/encoder/string.go | 459 + .../go-json/internal/encoder/string_table.go | 415 + .../go-json/internal/encoder/vm/debug_vm.go | 41 + .../goccy/go-json/internal/encoder/vm/hack.go | 9 + .../goccy/go-json/internal/encoder/vm/util.go | 207 + .../goccy/go-json/internal/encoder/vm/vm.go | 4859 +++++++++ .../internal/encoder/vm_color/debug_vm.go | 35 + .../go-json/internal/encoder/vm_color/hack.go | 9 + .../go-json/internal/encoder/vm_color/util.go | 274 + .../go-json/internal/encoder/vm_color/vm.go | 4859 +++++++++ .../encoder/vm_color_indent/debug_vm.go | 35 + .../internal/encoder/vm_color_indent/util.go | 297 + .../internal/encoder/vm_color_indent/vm.go | 4859 +++++++++ .../internal/encoder/vm_indent/debug_vm.go | 35 + .../internal/encoder/vm_indent/hack.go | 9 + .../internal/encoder/vm_indent/util.go | 230 + .../go-json/internal/encoder/vm_indent/vm.go | 4859 +++++++++ .../goccy/go-json/internal/errors/error.go | 183 + .../goccy/go-json/internal/runtime/rtype.go | 263 + .../go-json/internal/runtime/struct_field.go | 91 + .../goccy/go-json/internal/runtime/type.go | 100 + vendor/github.com/goccy/go-json/json.go | 371 + vendor/github.com/goccy/go-json/option.go | 79 + vendor/github.com/goccy/go-json/path.go | 84 + vendor/github.com/goccy/go-json/query.go | 47 + .../certificate-transparency-go/CHANGELOG.md | 143 +- .../certificate-transparency-go/README.md | 4 +- .../cloudbuild.yaml | 1 - .../cloudbuild_master.yaml | 1 - .../cloudbuild_tag.yaml | 1 - .../certificate-transparency-go/tls/tls.go | 2 +- .../certificate-transparency-go/types.go | 2 +- .../x509/root_unix.go | 4 +- .../x509/root_wasip1.go | 19 + .../x509/root_zos.go | 13 + .../github.com/google/gnostic-models/LICENSE | 203 + .../google/gnostic-models/compiler/README.md | 4 + .../google/gnostic-models/compiler/context.go | 49 + .../google/gnostic-models/compiler/error.go | 70 + .../gnostic-models/compiler/extensions.go | 86 + .../google/gnostic-models/compiler/helpers.go | 397 + .../google/gnostic-models/compiler/main.go | 16 + .../google/gnostic-models/compiler/reader.go | 307 + .../gnostic-models/extensions/README.md | 13 + .../gnostic-models/extensions/extension.pb.go | 461 + .../gnostic-models/extensions/extension.proto | 97 + .../gnostic-models/extensions/extensions.go | 64 + .../gnostic-models/jsonschema/README.md | 4 + .../google/gnostic-models/jsonschema/base.go | 97 + .../gnostic-models/jsonschema/display.go | 229 + .../gnostic-models/jsonschema/models.go | 228 + .../gnostic-models/jsonschema/operations.go | 394 + .../gnostic-models/jsonschema/reader.go | 442 + .../gnostic-models/jsonschema/schema.json | 150 + .../gnostic-models/jsonschema/writer.go | 369 + .../gnostic-models/openapiv2/OpenAPIv2.go | 8820 +++++++++++++++++ .../gnostic-models/openapiv2/OpenAPIv2.pb.go | 7342 ++++++++++++++ .../gnostic-models/openapiv2/OpenAPIv2.proto | 666 ++ .../google/gnostic-models/openapiv2/README.md | 14 + .../gnostic-models/openapiv2/document.go | 42 + .../gnostic-models/openapiv2/openapi-2.0.json | 1610 +++ .../openapiv3/OpenAPIv3.go | 9 +- .../openapiv3/OpenAPIv3.pb.go | 13 +- .../openapiv3/OpenAPIv3.proto | 2 +- .../openapiv3/README.md | 4 - .../openapiv3/annotations.pb.go | 21 +- .../openapiv3/annotations.proto | 12 +- .../openapiv3/document.go | 2 +- .../google/gnostic/openapiv3/openapi-3.0.json | 1251 --- .../google/gnostic/openapiv3/openapi-3.1.json | 1250 --- .../github.com/google/go-cmp/cmp/compare.go | 38 +- .../cmp/{export_unsafe.go => export.go} | 5 - .../google/go-cmp/cmp/export_panic.go | 16 - .../value/{pointer_unsafe.go => pointer.go} | 3 - .../cmp/internal/value/pointer_purego.go | 34 - .../github.com/google/go-cmp/cmp/options.go | 84 +- vendor/github.com/google/go-cmp/cmp/path.go | 46 +- .../google/go-cmp/cmp/report_reflect.go | 2 +- .../pkg/v1/layout/write.go | 1 + .../pkg/v1/mutate/mutate.go | 4 +- .../pkg/v1/remote/descriptor.go | 14 +- .../pkg/v1/remote/fetcher.go | 8 +- .../pkg/v1/remote/options.go | 3 +- .../pkg/v1/remote/transport/bearer.go | 137 +- .../pkg/v1/remote/transport/ping.go | 60 +- .../pkg/v1/remote/transport/schemer.go | 2 +- .../pkg/v1/remote/transport/transport.go | 47 +- .../pkg/v1/remote/write.go | 12 +- .../google/go-github/v50/github/event.go | 163 - .../go-github/v50/github/orgs_audit_log.go | 119 - .../google/go-github/{v50 => v55}/AUTHORS | 54 + .../google/go-github/{v50 => v55}/LICENSE | 0 .../go-github/{v50 => v55}/github/actions.go | 0 .../{v50 => v55}/github/actions_artifacts.go | 0 .../{v50 => v55}/github/actions_cache.go | 0 .../{v50 => v55}/github/actions_oidc.go | 0 .../v55/github/actions_required_workflows.go | 247 + .../github/actions_runner_groups.go | 0 .../{v50 => v55}/github/actions_runners.go | 55 + .../{v50 => v55}/github/actions_secrets.go | 0 .../{v50 => v55}/github/actions_variables.go | 0 .../github/actions_workflow_jobs.go | 1 + .../github/actions_workflow_runs.go | 36 +- .../{v50 => v55}/github/actions_workflows.go | 0 .../go-github/{v50 => v55}/github/activity.go | 0 .../{v50 => v55}/github/activity_events.go | 0 .../github/activity_notifications.go | 0 .../{v50 => v55}/github/activity_star.go | 0 .../{v50 => v55}/github/activity_watching.go | 0 .../go-github/{v50 => v55}/github/admin.go | 0 .../{v50 => v55}/github/admin_orgs.go | 0 .../{v50 => v55}/github/admin_stats.go | 3 +- .../{v50 => v55}/github/admin_users.go | 0 .../go-github/{v50 => v55}/github/apps.go | 25 +- .../{v50 => v55}/github/apps_hooks.go | 0 .../github/apps_hooks_deliveries.go | 0 .../{v50 => v55}/github/apps_installation.go | 0 .../{v50 => v55}/github/apps_manifest.go | 0 .../{v50 => v55}/github/apps_marketplace.go | 0 .../{v50 => v55}/github/authorizations.go | 0 .../go-github/{v50 => v55}/github/billing.go | 9 +- .../go-github/{v50 => v55}/github/checks.go | 0 .../{v50 => v55}/github/code-scanning.go | 264 +- .../google/go-github/v55/github/codespaces.go | 254 + .../v55/github/codespaces_secrets.go | 405 + .../{v50 => v55}/github/dependabot.go | 0 .../{v50 => v55}/github/dependabot_alerts.go | 10 +- .../{v50 => v55}/github/dependabot_secrets.go | 21 +- .../go-github/v55/github/dependency_graph.go | 80 + .../go-github/{v50 => v55}/github/doc.go | 28 +- .../{v50 => v55}/github/enterprise.go | 0 .../github/enterprise_actions_runners.go | 0 .../github/enterprise_audit_log.go | 0 .../enterprise_code_security_and_analysis.go | 0 .../google/go-github/v55/github/event.go | 54 + .../{v50 => v55}/github/event_types.go | 264 +- .../go-github/{v50 => v55}/github/gists.go | 0 .../{v50 => v55}/github/gists_comments.go | 0 .../go-github/{v50 => v55}/github/git.go | 0 .../{v50 => v55}/github/git_blobs.go | 0 .../{v50 => v55}/github/git_commits.go | 0 .../go-github/{v50 => v55}/github/git_refs.go | 0 .../go-github/{v50 => v55}/github/git_tags.go | 0 .../{v50 => v55}/github/git_trees.go | 0 .../{v50 => v55}/github/github-accessors.go | 2952 +++++- .../go-github/{v50 => v55}/github/github.go | 275 +- .../{v50 => v55}/github/gitignore.go | 0 .../{v50 => v55}/github/interactions.go | 0 .../{v50 => v55}/github/interactions_orgs.go | 0 .../{v50 => v55}/github/interactions_repos.go | 0 .../{v50 => v55}/github/issue_import.go | 9 +- .../go-github/{v50 => v55}/github/issues.go | 0 .../{v50 => v55}/github/issues_assignees.go | 0 .../{v50 => v55}/github/issues_comments.go | 0 .../{v50 => v55}/github/issues_events.go | 0 .../{v50 => v55}/github/issues_labels.go | 0 .../{v50 => v55}/github/issues_milestones.go | 0 .../{v50 => v55}/github/issues_timeline.go | 0 .../go-github/{v50 => v55}/github/licenses.go | 0 .../go-github/{v50 => v55}/github/messages.go | 176 +- .../{v50 => v55}/github/migrations.go | 0 .../github/migrations_source_import.go | 0 .../{v50 => v55}/github/migrations_user.go | 0 .../go-github/{v50 => v55}/github/misc.go | 0 .../go-github/{v50 => v55}/github/orgs.go | 19 +- .../github/orgs_actions_allowed.go | 0 .../github/orgs_actions_permissions.go | 0 .../go-github/v55/github/orgs_audit_log.go | 156 + .../github/orgs_credential_authorizations.go | 95 + .../{v50 => v55}/github/orgs_custom_roles.go | 0 .../{v50 => v55}/github/orgs_hooks.go | 0 .../v55/github/orgs_hooks_configuration.go | 49 + .../github/orgs_hooks_deliveries.go | 0 .../{v50 => v55}/github/orgs_members.go | 4 +- .../github/orgs_outside_collaborators.go | 0 .../{v50 => v55}/github/orgs_packages.go | 0 .../v55/github/orgs_personal_access_tokens.go | 34 + .../{v50 => v55}/github/orgs_projects.go | 0 .../google/go-github/v55/github/orgs_rules.go | 105 + .../github/orgs_security_managers.go | 0 .../github/orgs_users_blocking.go | 0 .../go-github/{v50 => v55}/github/packages.go | 0 .../go-github/{v50 => v55}/github/projects.go | 0 .../go-github/{v50 => v55}/github/pulls.go | 3 +- .../{v50 => v55}/github/pulls_comments.go | 2 + .../{v50 => v55}/github/pulls_reviewers.go | 0 .../{v50 => v55}/github/pulls_reviews.go | 0 .../{v50 => v55}/github/pulls_threads.go | 0 .../{v50 => v55}/github/reactions.go | 0 .../go-github/{v50 => v55}/github/repos.go | 94 +- .../github/repos_actions_access.go | 0 .../github/repos_actions_allowed.go | 0 .../github/repos_actions_permissions.go | 0 .../{v50 => v55}/github/repos_autolinks.go | 0 .../{v50 => v55}/github/repos_codeowners.go | 0 .../github/repos_collaborators.go | 0 .../{v50 => v55}/github/repos_comments.go | 0 .../{v50 => v55}/github/repos_commits.go | 0 .../github/repos_community_health.go | 0 .../{v50 => v55}/github/repos_contents.go | 22 +- .../repos_deployment_branch_policies.go | 0 .../{v50 => v55}/github/repos_deployments.go | 0 .../{v50 => v55}/github/repos_environments.go | 6 + .../{v50 => v55}/github/repos_forks.go | 0 .../{v50 => v55}/github/repos_hooks.go | 0 .../v55/github/repos_hooks_configuration.go | 49 + .../github/repos_hooks_deliveries.go | 4 +- .../{v50 => v55}/github/repos_invitations.go | 0 .../{v50 => v55}/github/repos_keys.go | 0 .../{v50 => v55}/github/repos_lfs.go | 0 .../{v50 => v55}/github/repos_merging.go | 0 .../{v50 => v55}/github/repos_pages.go | 68 +- .../github/repos_prereceive_hooks.go | 0 .../{v50 => v55}/github/repos_projects.go | 0 .../{v50 => v55}/github/repos_releases.go | 0 .../go-github/v55/github/repos_rules.go | 464 + .../{v50 => v55}/github/repos_stats.go | 0 .../{v50 => v55}/github/repos_statuses.go | 0 .../{v50 => v55}/github/repos_tags.go | 0 .../{v50 => v55}/github/repos_traffic.go | 0 .../go-github/{v50 => v55}/github/scim.go | 0 .../go-github/{v50 => v55}/github/search.go | 0 .../{v50 => v55}/github/secret_scanning.go | 24 +- .../v55/github/security_advisories.go | 37 + .../go-github/{v50 => v55}/github/strings.go | 0 .../go-github/{v50 => v55}/github/teams.go | 0 .../github/teams_discussion_comments.go | 0 .../{v50 => v55}/github/teams_discussions.go | 0 .../{v50 => v55}/github/teams_members.go | 0 .../{v50 => v55}/github/timestamp.go | 8 + .../go-github/{v50 => v55}/github/users.go | 4 +- .../github/users_administration.go | 0 .../{v50 => v55}/github/users_blocking.go | 0 .../{v50 => v55}/github/users_emails.go | 25 + .../{v50 => v55}/github/users_followers.go | 0 .../{v50 => v55}/github/users_gpg_keys.go | 0 .../{v50 => v55}/github/users_keys.go | 2 + .../{v50 => v55}/github/users_packages.go | 0 .../{v50 => v55}/github/users_projects.go | 0 .../github/users_ssh_signing_keys.go | 0 .../{v50 => v55}/github/with_appengine.go | 0 .../{v50 => v55}/github/without_appengine.go | 0 .../github.com/google/pprof/profile/encode.go | 6 +- .../github.com/google/pprof/profile/merge.go | 99 + .../google/pprof/profile/profile.go | 47 +- vendor/github.com/google/s2a-go/README.md | 7 +- .../internal/handshaker/service/service.go | 53 +- .../s2a-go/internal/record/ticketsender.go | 8 +- .../google/s2a-go/internal/v2/s2av2.go | 105 +- .../github.com/google/s2a-go/retry/retry.go | 144 + vendor/github.com/google/s2a-go/s2a.go | 47 +- .../github.com/google/s2a-go/s2a_options.go | 7 + .../s2a-go/testdata/mds_client_cert.pem | 19 + .../google/s2a-go/testdata/mds_client_key.pem | 28 + .../google/s2a-go/testdata/mds_root_cert.pem | 21 + .../s2a-go/testdata/mds_server_cert.pem | 21 + .../google/s2a-go/testdata/mds_server_key.pem | 28 + .../s2a-go/testdata/self_signed_cert.pem | 19 + .../s2a-go/testdata/self_signed_key.pem | 28 + vendor/github.com/google/uuid/.travis.yml | 9 - vendor/github.com/google/uuid/CHANGELOG.md | 21 + vendor/github.com/google/uuid/CONTRIBUTING.md | 16 + vendor/github.com/google/uuid/README.md | 10 +- vendor/github.com/google/uuid/node_js.go | 2 +- vendor/github.com/google/uuid/uuid.go | 36 +- .../client/client.go | 42 +- .../client/util/util.go | 9 + vendor/github.com/gowebpki/jcs/.gitignore | 34 + vendor/github.com/gowebpki/jcs/LICENSE | 202 + vendor/github.com/gowebpki/jcs/README.md | 72 + vendor/github.com/gowebpki/jcs/es6numfmt.go | 59 + vendor/github.com/gowebpki/jcs/jcs.go | 489 + .../hashicorp/go-retryablehttp/CHANGELOG.md | 9 + .../hashicorp/go-retryablehttp/CODEOWNERS | 1 + .../hashicorp/go-retryablehttp/LICENSE | 2 + .../hashicorp/go-retryablehttp/client.go | 16 +- .../go-retryablehttp/roundtripper.go | 3 + vendor/github.com/hashicorp/hcl/decoder.go | 46 +- .../github.com/hashicorp/hcl/hcl/ast/ast.go | 15 +- vendor/github.com/imdario/mergo/README.md | 20 +- .../github.com/jedisct1/go-minisign/LICENSE | 2 +- .../klauspost/compress/.goreleaser.yml | 20 +- .../github.com/klauspost/compress/README.md | 29 + .../github.com/klauspost/compress/SECURITY.md | 25 + .../klauspost/compress/flate/deflate.go | 34 +- .../klauspost/compress/flate/fast_encoder.go | 23 - .../compress/flate/huffman_bit_writer.go | 5 - .../compress/flate/huffman_sortByFreq.go | 19 - .../klauspost/compress/flate/inflate.go | 66 +- .../klauspost/compress/flate/inflate_gen.go | 34 +- .../klauspost/compress/flate/level5.go | 398 + .../compress/flate/matchlen_amd64.go | 16 + .../klauspost/compress/flate/matchlen_amd64.s | 68 + .../compress/flate/matchlen_generic.go | 33 + .../klauspost/compress/fse/bitwriter.go | 3 +- .../klauspost/compress/fse/compress.go | 3 +- .../klauspost/compress/huff0/bitwriter.go | 11 +- .../klauspost/compress/huff0/compress.go | 20 +- .../klauspost/compress/huff0/decompress.go | 2 +- .../compress/internal/snapref/encode_other.go | 12 - .../klauspost/compress/zstd/README.md | 2 +- .../klauspost/compress/zstd/bitreader.go | 34 +- .../klauspost/compress/zstd/bitwriter.go | 3 +- .../klauspost/compress/zstd/blockdec.go | 2 +- .../klauspost/compress/zstd/blockenc.go | 29 +- .../compress/zstd/decoder_options.go | 2 +- .../klauspost/compress/zstd/dict.go | 379 +- .../klauspost/compress/zstd/enc_base.go | 1 + .../klauspost/compress/zstd/enc_best.go | 11 +- .../klauspost/compress/zstd/enc_dfast.go | 2 +- .../klauspost/compress/zstd/enc_fast.go | 17 +- .../klauspost/compress/zstd/encoder.go | 13 +- .../compress/zstd/encoder_options.go | 2 +- .../klauspost/compress/zstd/framedec.go | 8 +- .../klauspost/compress/zstd/frameenc.go | 4 +- .../klauspost/compress/zstd/matchlen_amd64.go | 16 + .../klauspost/compress/zstd/matchlen_amd64.s | 68 + .../compress/zstd/matchlen_generic.go | 33 + .../klauspost/compress/zstd/seqdec.go | 17 +- .../klauspost/compress/zstd/seqdec_amd64.s | 128 +- .../klauspost/compress/zstd/seqdec_generic.go | 2 +- .../klauspost/compress/zstd/snappy.go | 5 +- .../klauspost/compress/zstd/zstd.go | 22 - vendor/github.com/klauspost/pgzip/.travis.yml | 4 + vendor/github.com/klauspost/pgzip/LICENSE | 3 +- vendor/github.com/klauspost/pgzip/README.md | 13 +- vendor/github.com/klauspost/pgzip/gunzip.go | 13 + .../lestrrat-go/blackmagic/.gitignore | 15 + .../github.com/lestrrat-go/blackmagic/LICENSE | 21 + .../lestrrat-go/blackmagic/README.md | 3 + .../lestrrat-go/blackmagic/blackmagic.go | 90 + .../github.com/lestrrat-go/httpcc/.gitignore | 15 + vendor/github.com/lestrrat-go/httpcc/LICENSE | 21 + .../github.com/lestrrat-go/httpcc/README.md | 35 + .../lestrrat-go/httpcc/directives.go | 117 + .../github.com/lestrrat-go/httpcc/httpcc.go | 310 + .../github.com/lestrrat-go/httprc/.gitignore | 15 + .../lestrrat-go/httprc/.golangci.yml | 84 + vendor/github.com/lestrrat-go/httprc/Changes | 17 + vendor/github.com/lestrrat-go/httprc/LICENSE | 21 + .../github.com/lestrrat-go/httprc/README.md | 130 + vendor/github.com/lestrrat-go/httprc/cache.go | 172 + .../github.com/lestrrat-go/httprc/fetcher.go | 182 + .../github.com/lestrrat-go/httprc/httprc.go | 22 + .../lestrrat-go/httprc/options.yaml | 119 + .../lestrrat-go/httprc/options_gen.go | 221 + vendor/github.com/lestrrat-go/httprc/queue.go | 459 + .../lestrrat-go/httprc/whitelist.go | 73 + vendor/github.com/lestrrat-go/iter/LICENSE | 21 + .../lestrrat-go/iter/arrayiter/arrayiter.go | 192 + .../lestrrat-go/iter/mapiter/mapiter.go | 195 + .../jwx/v2}/LICENSE | 5 +- .../lestrrat-go/jwx/v2/cert/BUILD.bazel | 32 + .../lestrrat-go/jwx/v2/cert/cert.go | 48 + .../lestrrat-go/jwx/v2/cert/chain.go | 78 + .../jwx/v2/internal/base64/BUILD.bazel | 21 + .../jwx/v2/internal/base64/asmbase64.go | 39 + .../jwx/v2/internal/base64/base64.go | 134 + .../jwx/v2/internal/ecutil/BUILD.bazel | 15 + .../jwx/v2/internal/ecutil/ecutil.go | 114 + .../jwx/v2/internal/iter/BUILD.bazel | 15 + .../jwx/v2/internal/iter/mapiter.go | 36 + .../jwx/v2/internal/json/BUILD.bazel | 19 + .../lestrrat-go/jwx/v2/internal/json/goccy.go | 51 + .../lestrrat-go/jwx/v2/internal/json/json.go | 112 + .../jwx/v2/internal/json/registry.go | 52 + .../jwx/v2/internal/json/stdlib.go | 49 + .../jwx/v2/internal/keyconv/BUILD.bazel | 31 + .../jwx/v2/internal/keyconv/keyconv.go | 177 + .../jwx/v2/internal/pool/BUILD.bazel | 14 + .../lestrrat-go/jwx/v2/internal/pool/pool.go | 61 + .../lestrrat-go/jwx/v2/jwa/BUILD.bazel | 39 + .../lestrrat-go/jwx/v2/jwa/README.md | 3 + .../lestrrat-go/jwx/v2/jwa/compression_gen.go | 101 + .../jwx/v2/jwa/content_encryption_gen.go | 109 + .../lestrrat-go/jwx/v2/jwa/elliptic_gen.go | 112 + .../github.com/lestrrat-go/jwx/v2/jwa/jwa.go | 61 + .../jwx/v2/jwa/key_encryption_gen.go | 140 + .../lestrrat-go/jwx/v2/jwa/key_type_gen.go | 106 + .../lestrrat-go/jwx/v2/jwa/secp2561k.go | 11 + .../lestrrat-go/jwx/v2/jwa/signature_gen.go | 127 + .../lestrrat-go/jwx/v2/jwk/BUILD.bazel | 78 + .../lestrrat-go/jwx/v2/jwk/README.md | 217 + .../lestrrat-go/jwx/v2/jwk/cache.go | 410 + .../lestrrat-go/jwx/v2/jwk/ecdsa.go | 273 + .../lestrrat-go/jwx/v2/jwk/ecdsa_gen.go | 1189 +++ .../lestrrat-go/jwx/v2/jwk/es256k.go | 14 + .../lestrrat-go/jwx/v2/jwk/fetch.go | 134 + .../lestrrat-go/jwx/v2/jwk/interface.go | 144 + .../lestrrat-go/jwx/v2/jwk/interface_gen.go | 130 + .../github.com/lestrrat-go/jwx/v2/jwk/io.go | 39 + .../github.com/lestrrat-go/jwx/v2/jwk/jwk.go | 789 ++ .../lestrrat-go/jwx/v2/jwk/key_ops.go | 58 + .../github.com/lestrrat-go/jwx/v2/jwk/okp.go | 227 + .../lestrrat-go/jwx/v2/jwk/okp_gen.go | 1127 +++ .../lestrrat-go/jwx/v2/jwk/options.go | 38 + .../lestrrat-go/jwx/v2/jwk/options.yaml | 142 + .../lestrrat-go/jwx/v2/jwk/options_gen.go | 274 + .../github.com/lestrrat-go/jwx/v2/jwk/rsa.go | 283 + .../lestrrat-go/jwx/v2/jwk/rsa_gen.go | 1258 +++ .../github.com/lestrrat-go/jwx/v2/jwk/set.go | 338 + .../lestrrat-go/jwx/v2/jwk/symmetric.go | 67 + .../lestrrat-go/jwx/v2/jwk/symmetric_gen.go | 520 + .../lestrrat-go/jwx/v2/jwk/usage.go | 30 + .../lestrrat-go/jwx/v2/jwk/whitelist.go | 69 + .../lestrrat-go/jwx/v2/jws/BUILD.bazel | 71 + .../lestrrat-go/jwx/v2/jws/README.md | 111 + .../lestrrat-go/jwx/v2/jws/ecdsa.go | 206 + .../lestrrat-go/jwx/v2/jws/eddsa.go | 77 + .../lestrrat-go/jwx/v2/jws/es256k.go | 12 + .../lestrrat-go/jwx/v2/jws/headers.go | 71 + .../lestrrat-go/jwx/v2/jws/headers_gen.go | 565 ++ .../github.com/lestrrat-go/jwx/v2/jws/hmac.go | 77 + .../lestrrat-go/jwx/v2/jws/interface.go | 106 + .../github.com/lestrrat-go/jwx/v2/jws/io.go | 33 + .../github.com/lestrrat-go/jwx/v2/jws/jws.go | 856 ++ .../lestrrat-go/jwx/v2/jws/key_provider.go | 276 + .../lestrrat-go/jwx/v2/jws/message.go | 503 + .../lestrrat-go/jwx/v2/jws/options.go | 226 + .../lestrrat-go/jwx/v2/jws/options.yaml | 193 + .../lestrrat-go/jwx/v2/jws/options_gen.go | 362 + .../github.com/lestrrat-go/jwx/v2/jws/rsa.go | 146 + .../lestrrat-go/jwx/v2/jws/signer.go | 106 + .../lestrrat-go/jwx/v2/jws/verifier.go | 96 + .../lestrrat-go/jwx/v2/x25519/BUILD.bazel | 24 + .../lestrrat-go/jwx/v2/x25519/x25519.go | 115 + .../github.com/lestrrat-go/option/.gitignore | 15 + vendor/github.com/lestrrat-go/option/LICENSE | 21 + .../github.com/lestrrat-go/option/README.md | 245 + .../github.com/lestrrat-go/option/option.go | 38 + .../letsencrypt/boulder/core/challenges.go | 18 + .../letsencrypt/boulder/core/interfaces.go | 7 +- .../letsencrypt/boulder/core/objects.go | 139 +- .../letsencrypt/boulder/core/proto/core.pb.go | 1182 --- .../letsencrypt/boulder/core/proto/core.proto | 101 - .../letsencrypt/boulder/core/util.go | 47 +- .../letsencrypt/boulder/errors/errors.go | 194 - .../boulder/features/featureflag_string.go | 56 - .../letsencrypt/boulder/features/features.go | 203 - .../letsencrypt/boulder/goodkey/blocked.go | 5 +- .../letsencrypt/boulder/goodkey/good_key.go | 53 +- .../letsencrypt/boulder/probs/probs.go | 328 +- .../letsencrypt/boulder/sa/proto/sa.pb.go | 4261 -------- .../letsencrypt/boulder/sa/proto/sa.proto | 353 - .../boulder/sa/proto/sa_grpc.pb.go | 2937 ------ .../letsencrypt/boulder/sa/proto/subsets.go | 47 - .../letsencrypt/boulder/strictyaml/yaml.go | 46 + .../github.com/mattn/go-isatty/isatty_bsd.go | 3 +- .../mattn/go-isatty/isatty_others.go | 5 +- .../mattn/go-isatty/isatty_tcgets.go | 3 +- .../golang_protobuf_extensions/v2/LICENSE | 201 + .../{ => v2}/NOTICE | 0 .../{ => v2}/pbutil/.gitignore | 0 .../{ => v2}/pbutil/Makefile | 0 .../{ => v2}/pbutil/decode.go | 16 +- .../{ => v2}/pbutil/doc.go | 0 .../{ => v2}/pbutil/encode.go | 5 +- .../reflections}/.gitignore | 2 - .../github.com/oleiade/reflections/AUTHORS.md | 9 + vendor/github.com/oleiade/reflections/LICENSE | 20 + .../github.com/oleiade/reflections/README.md | 235 + .../oleiade/reflections/reflections.go | 301 + .../go-digest}/digestset/set.go | 15 + .../image-spec/specs-go/v1/annotations.go | 6 - .../image-spec/specs-go/v1/descriptor.go | 12 +- .../image-spec/specs-go/v1/index.go | 6 + .../image-spec/specs-go/v1/layout.go | 6 +- .../image-spec/specs-go/v1/manifest.go | 8 - .../image-spec/specs-go/v1/mediatype.go | 4 +- .../image-spec/specs-go/version.go | 2 +- .../outcaste-io/ristretto/.deepsource.toml | 17 + .../github.com/outcaste-io/ristretto/.mailmap | 1 + .../outcaste-io/ristretto/CHANGELOG.md | 172 + .../github.com/outcaste-io/ristretto/LICENSE | 176 + .../outcaste-io/ristretto/README.md | 237 + .../github.com/outcaste-io/ristretto/cache.go | 520 + .../outcaste-io/ristretto/metrics.go | 249 + .../outcaste-io/ristretto/policy.go | 388 + .../github.com/outcaste-io/ristretto/ring.go | 91 + .../outcaste-io/ristretto/sketch.go | 155 + .../github.com/outcaste-io/ristretto/store.go | 225 + .../github.com/outcaste-io/ristretto/test.sh | 20 + .../github.com/outcaste-io/ristretto/ttl.go | 155 + .../outcaste-io/ristretto/z/LICENSE | 64 + .../outcaste-io/ristretto/z/README.md | 129 + .../outcaste-io/ristretto/z/allocator.go | 403 + .../outcaste-io/ristretto/z/bbloom.go | 209 + .../outcaste-io/ristretto/z/btree.go | 710 ++ .../outcaste-io/ristretto/z/buffer.go | 543 + .../outcaste-io/ristretto/z/calloc.go | 42 + .../outcaste-io/ristretto/z/calloc_32bit.go | 14 + .../outcaste-io/ristretto/z/calloc_64bit.go | 14 + .../ristretto/z/calloc_jemalloc.go | 173 + .../ristretto/z/calloc_nojemalloc.go | 37 + .../outcaste-io/ristretto/z/file.go | 217 + .../outcaste-io/ristretto/z/file_default.go | 39 + .../outcaste-io/ristretto/z/file_linux.go | 37 + .../outcaste-io/ristretto/z/flags.go | 324 + .../outcaste-io/ristretto/z/histogram.go | 205 + .../outcaste-io/ristretto/z/mmap.go | 44 + .../outcaste-io/ristretto/z/mmap_darwin.go | 59 + .../outcaste-io/ristretto/z/mmap_linux.go | 97 + .../outcaste-io/ristretto/z/mmap_plan9.go | 44 + .../outcaste-io/ristretto/z/mmap_unix.go | 56 + .../outcaste-io/ristretto/z/mmap_wasip1.go | 40 + .../outcaste-io/ristretto/z/mmap_windows.go | 95 + .../outcaste-io/ristretto/z/rtutil.go | 75 + .../outcaste-io/ristretto/z/rtutil.s | 0 .../outcaste-io/ristretto/z/simd/baseline.go | 127 + .../outcaste-io/ristretto/z/simd/search.go | 51 + .../ristretto/z/simd/search_amd64.s | 60 + .../ristretto/z/simd/stub_search_amd64.go | 6 + .../github.com/outcaste-io/ristretto/z/z.go | 163 + .../pelletier/go-toml/v2/.goreleaser.yaml | 3 + .../github.com/pelletier/go-toml/v2/LICENSE | 3 +- .../github.com/pelletier/go-toml/v2/README.md | 44 +- vendor/github.com/pelletier/go-toml/v2/ci.sh | 1 + .../github.com/pelletier/go-toml/v2/decode.go | 2 +- .../pelletier/go-toml/v2/marshaler.go | 40 +- .../pelletier/go-toml/v2/unmarshaler.go | 16 +- .../pelletier/go-toml/v2/unstable/parser.go | 6 + vendor/github.com/philhofer/fwd/LICENSE.md | 7 + vendor/github.com/philhofer/fwd/README.md | 359 + vendor/github.com/philhofer/fwd/reader.go | 383 + vendor/github.com/philhofer/fwd/writer.go | 236 + .../philhofer/fwd/writer_appengine.go | 6 + .../github.com/philhofer/fwd/writer_tinygo.go | 19 + .../github.com/philhofer/fwd/writer_unsafe.go | 20 + .../prometheus/collectors/expvar_collector.go | 2 +- .../collectors/go_collector_latest.go | 9 +- .../client_golang/prometheus/counter.go | 26 +- .../client_golang/prometheus/desc.go | 32 +- .../prometheus/expvar_collector.go | 2 +- .../client_golang/prometheus/gauge.go | 8 +- .../client_golang/prometheus/histogram.go | 126 +- .../prometheus/internal/difflib.go | 2 +- .../client_golang/prometheus/labels.go | 58 +- .../client_golang/prometheus/metric.go | 3 + .../client_golang/prometheus/promhttp/http.go | 19 +- .../prometheus/promhttp/instrument_server.go | 9 +- .../client_golang/prometheus/registry.go | 6 +- .../client_golang/prometheus/summary.go | 41 +- .../client_golang/prometheus/value.go | 55 +- .../client_golang/prometheus/vec.go | 87 +- .../prometheus/client_model/go/metrics.pb.go | 350 +- .../prometheus/common/expfmt/decode.go | 7 +- .../prometheus/common/expfmt/encode.go | 15 +- .../prometheus/common/expfmt/expfmt.go | 26 +- .../prometheus/common/expfmt/text_parse.go | 2 +- .../prometheus/procfs/.golangci.yml | 3 + .../prometheus/procfs/Makefile.common | 22 +- vendor/github.com/prometheus/procfs/README.md | 4 +- vendor/github.com/prometheus/procfs/arp.go | 6 +- .../github.com/prometheus/procfs/buddyinfo.go | 6 +- .../github.com/prometheus/procfs/cpuinfo.go | 17 +- vendor/github.com/prometheus/procfs/crypto.go | 7 +- vendor/github.com/prometheus/procfs/fs.go | 11 +- .../prometheus/procfs/fs_statfs_notype.go | 23 + .../prometheus/procfs/fs_statfs_type.go | 33 + .../github.com/prometheus/procfs/fscache.go | 6 +- .../prometheus/procfs/internal/util/parse.go | 15 + vendor/github.com/prometheus/procfs/ipvs.go | 7 +- .../github.com/prometheus/procfs/loadavg.go | 4 +- vendor/github.com/prometheus/procfs/mdstat.go | 36 +- .../github.com/prometheus/procfs/meminfo.go | 4 +- .../github.com/prometheus/procfs/mountinfo.go | 10 +- .../prometheus/procfs/mountstats.go | 117 +- .../prometheus/procfs/net_conntrackstat.go | 91 +- .../prometheus/procfs/net_ip_socket.go | 32 +- .../prometheus/procfs/net_protocols.go | 4 +- .../github.com/prometheus/procfs/net_route.go | 143 + .../prometheus/procfs/net_sockstat.go | 9 +- .../prometheus/procfs/net_softnet.go | 9 +- .../github.com/prometheus/procfs/net_unix.go | 16 +- .../prometheus/procfs/net_wireless.go | 182 + .../github.com/prometheus/procfs/net_xfrm.go | 2 +- .../github.com/prometheus/procfs/netstat.go | 25 +- vendor/github.com/prometheus/procfs/proc.go | 37 +- .../prometheus/procfs/proc_cgroup.go | 4 +- .../prometheus/procfs/proc_cgroups.go | 8 +- .../prometheus/procfs/proc_fdinfo.go | 10 +- .../prometheus/procfs/proc_interrupts.go | 2 +- .../prometheus/procfs/proc_limits.go | 4 +- .../github.com/prometheus/procfs/proc_maps.go | 24 +- .../prometheus/procfs/proc_netstat.go | 4 +- .../github.com/prometheus/procfs/proc_ns.go | 6 +- .../github.com/prometheus/procfs/proc_psi.go | 6 +- .../prometheus/procfs/proc_smaps.go | 4 +- .../github.com/prometheus/procfs/proc_snmp.go | 4 +- .../github.com/prometheus/procfs/proc_stat.go | 8 +- .../prometheus/procfs/proc_status.go | 53 +- .../github.com/prometheus/procfs/proc_sys.go | 2 +- vendor/github.com/prometheus/procfs/slab.go | 2 +- .../github.com/prometheus/procfs/softirqs.go | 24 +- vendor/github.com/prometheus/procfs/stat.go | 28 +- vendor/github.com/prometheus/procfs/swaps.go | 8 +- vendor/github.com/prometheus/procfs/thread.go | 11 +- vendor/github.com/prometheus/procfs/vm.go | 2 +- .../github.com/prometheus/procfs/zoneinfo.go | 4 +- .../github.com/puzpuzpuz/xsync/v2/.gitignore | 15 + .../puzpuzpuz/xsync/v2/BENCHMARKS.md | 131 + vendor/github.com/puzpuzpuz/xsync/v2/LICENSE | 21 + .../github.com/puzpuzpuz/xsync/v2/README.md | 148 + .../github.com/puzpuzpuz/xsync/v2/counter.go | 99 + vendor/github.com/puzpuzpuz/xsync/v2/map.go | 785 ++ vendor/github.com/puzpuzpuz/xsync/v2/mapof.go | 688 ++ .../puzpuzpuz/xsync/v2/mpmcqueue.go | 137 + .../puzpuzpuz/xsync/v2/mpmcqueueof.go | 150 + .../github.com/puzpuzpuz/xsync/v2/rbmutex.go | 145 + vendor/github.com/puzpuzpuz/xsync/v2/util.go | 63 + .../puzpuzpuz/xsync/v2/util_mapof.go | 22 + vendor/github.com/rivo/uniseg/README.md | 7 + vendor/github.com/rivo/uniseg/doc.go | 6 +- vendor/github.com/rivo/uniseg/grapheme.go | 25 +- .../github.com/rivo/uniseg/graphemerules.go | 2 +- vendor/github.com/rivo/uniseg/line.go | 7 +- vendor/github.com/rivo/uniseg/sentence.go | 4 +- vendor/github.com/rivo/uniseg/step.go | 4 +- vendor/github.com/rivo/uniseg/word.go | 4 +- .../sagikazarmark/locafero/.editorconfig | 21 + .../github.com/sagikazarmark/locafero/.envrc | 4 + .../sagikazarmark/locafero/.gitignore | 8 + .../sagikazarmark/locafero/.golangci.yaml | 27 + .../github.com/sagikazarmark/locafero/LICENSE | 19 + .../sagikazarmark/locafero/README.md | 37 + .../sagikazarmark/locafero/file_type.go | 28 + .../sagikazarmark/locafero/finder.go | 165 + .../sagikazarmark/locafero/flake.lock | 273 + .../sagikazarmark/locafero/flake.nix | 47 + .../sagikazarmark/locafero/helpers.go | 41 + .../sagikazarmark/locafero/justfile | 11 + .../sagikazarmark/slog-shim/.editorconfig | 18 + .../github.com/sagikazarmark/slog-shim/.envrc | 4 + .../sagikazarmark/slog-shim/.gitignore | 4 + .../sagikazarmark/slog-shim/LICENSE | 27 + .../sagikazarmark/slog-shim/README.md | 81 + .../sagikazarmark/slog-shim/attr.go | 74 + .../sagikazarmark/slog-shim/attr_120.go | 75 + .../sagikazarmark/slog-shim/flake.lock | 273 + .../sagikazarmark/slog-shim/flake.nix | 57 + .../sagikazarmark/slog-shim/handler.go | 45 + .../sagikazarmark/slog-shim/handler_120.go | 45 + .../sagikazarmark/slog-shim/json_handler.go | 23 + .../slog-shim/json_handler_120.go | 24 + .../sagikazarmark/slog-shim/level.go | 61 + .../sagikazarmark/slog-shim/level_120.go | 61 + .../sagikazarmark/slog-shim/logger.go | 98 + .../sagikazarmark/slog-shim/logger_120.go | 99 + .../sagikazarmark/slog-shim/record.go | 31 + .../sagikazarmark/slog-shim/record_120.go | 32 + .../sagikazarmark/slog-shim/text_handler.go | 23 + .../slog-shim/text_handler_120.go | 24 + .../sagikazarmark/slog-shim/value.go | 109 + .../sagikazarmark/slog-shim/value_120.go | 110 + .../encrypted/encrypted.go | 102 +- vendor/github.com/segmentio/asm/LICENSE | 21 + .../github.com/segmentio/asm/base64/base64.go | 67 + .../segmentio/asm/base64/base64_amd64.go | 78 + .../segmentio/asm/base64/base64_arm64.go | 42 + .../segmentio/asm/base64/base64_asm.go | 94 + .../segmentio/asm/base64/base64_default.go | 14 + .../segmentio/asm/base64/decode_amd64.go | 9 + .../segmentio/asm/base64/decode_amd64.s | 143 + .../segmentio/asm/base64/decode_arm64.go | 7 + .../segmentio/asm/base64/decode_arm64.s | 203 + .../segmentio/asm/base64/encode_amd64.go | 7 + .../segmentio/asm/base64/encode_amd64.s | 87 + .../segmentio/asm/base64/encode_arm64.go | 6 + .../segmentio/asm/base64/encode_arm64.s | 97 + .../github.com/segmentio/asm/cpu/arm/arm.go | 80 + .../segmentio/asm/cpu/arm64/arm64.go | 74 + vendor/github.com/segmentio/asm/cpu/cpu.go | 22 + .../segmentio/asm/cpu/cpuid/cpuid.go | 32 + .../github.com/segmentio/asm/cpu/x86/x86.go | 76 + .../asm/internal/unsafebytes/unsafebytes.go | 20 + .../v2/cmd/cosign/cli/options/attach.go | 3 + .../cosign/v2/cmd/cosign/cli/options/clean.go | 2 +- .../cosign/v2/cmd/cosign/cli/options/copy.go | 10 +- .../cosign/cli/options/deprecate.go} | 27 +- .../cosign/v2/cmd/cosign/cli/options/key.go | 4 + .../v2/cmd/cosign/cli/options/predicate.go | 11 +- .../v2/cmd/cosign/cli/options/registry.go | 14 + .../cosign/v2/cmd/cosign/cli/options/sign.go | 20 +- .../v2/cmd/cosign/cli/options/signblob.go | 16 + .../v2/cmd/cosign/cli/options/triangulate.go | 2 +- .../v2/cmd/cosign/cli/options/verify.go | 8 +- .../v2/pkg/cosign/attestation/attestation.go | 35 +- .../cosign/v2/pkg/cosign/bundle/rekor.go | 4 +- .../sigstore/cosign/v2/pkg/cosign/env/env.go | 18 +- .../sigstore/cosign/v2/pkg/cosign/fetch.go | 10 + .../cosign/v2/pkg/cosign/git/github/github.go | 4 +- .../sigstore/cosign/v2/pkg/cosign/keys.go | 3 +- .../cosign/v2/pkg/cosign/kubernetes/secret.go | 5 +- .../v2/pkg/cosign/pkcs11key/pkcs11key.go | 13 +- .../sigstore/cosign/v2/pkg/cosign/tlog.go | 14 +- .../sigstore/cosign/v2/pkg/cosign/verify.go | 81 +- .../cosign/v2/pkg/oci/mutate/mutate.go | 146 +- .../cosign/v2/pkg/oci/mutate/signatures.go | 14 +- .../cosign/v2/pkg/oci/remote/remote.go | 48 +- .../sigstore/cosign/v2/pkg/oci/static/file.go | 11 - .../cosign/v2/pkg/providers/github/github.go | 23 +- .../generated/models/alpine_v001_schema.go | 7 + .../pkg/generated/models/cose_v001_schema.go | 11 + .../pkg/generated/models/dsse_v001_schema.go | 20 + .../models/hashedrekord_v001_schema.go | 12 + .../pkg/generated/models/helm_v001_schema.go | 13 + .../generated/models/intoto_v001_schema.go | 11 + .../generated/models/intoto_v002_schema.go | 17 + .../pkg/generated/models/jar_v001_schema.go | 12 + .../rekor/pkg/generated/models/log_entry.go | 17 +- .../rekor/pkg/generated/models/log_info.go | 5 + .../generated/models/rekord_v001_schema.go | 8 + .../generated/models/rfc3161_v001_schema.go | 1 + .../pkg/generated/models/rpm_v001_schema.go | 7 + .../pkg/generated/models/search_index.go | 5 + .../pkg/generated/models/search_log_query.go | 4 + .../pkg/generated/models/tuf_v001_schema.go | 2 + .../rekor/pkg/pki/identity/identity.go | 38 + .../rekor/pkg/pki/minisign/minisign.go | 18 +- .../sigstore/rekor/pkg/pki/pgp/pgp.go | 44 +- .../sigstore/rekor/pkg/pki/pkcs7/pkcs7.go | 33 +- .../github.com/sigstore/rekor/pkg/pki/pki.go | 5 +- .../sigstore/rekor/pkg/pki/ssh/ssh.go | 112 +- .../sigstore/rekor/pkg/pki/tuf/tuf.go | 59 +- .../sigstore/rekor/pkg/pki/x509/x509.go | 53 +- .../rekor/pkg/types/dsse/v0.0.1/entry.go | 20 +- .../sigstore/rekor/pkg/types/entries.go | 5 +- .../pkg/types/hashedrekord/v0.0.1/entry.go | 15 +- .../sigstore/rekor/pkg/types/intoto/README.md | 2 +- .../rekor/pkg/types/intoto/v0.0.1/entry.go | 15 +- .../rekor/pkg/types/intoto/v0.0.2/entry.go | 19 +- .../rekor/pkg/types/rekord/v0.0.1/entry.go | 23 +- .../sigstore/rekor/pkg/types/test_util.go | 6 +- .../sigstore/rekor/pkg/util/checkpoint.go | 2 +- .../sigstore/pkg/cryptoutils/privatekey.go | 2 +- .../sigstore/pkg/signature/payload/payload.go | 2 +- .../sigstore/sigstore/pkg/tuf/client.go | 21 +- .../sigstore/pkg/tuf/repository/root.json | 144 +- .../pkg/tuf/repository/targets/ctfe_2022.pub | 4 + .../targets/fulcio_intermediate_v1.crt.pem | 14 + .../pkg/tuf/repository/targets/rekor.0.pub | 4 - .../pkg/tuf/repository/targets/rekor.json | 23 - .../tuf/repository/targets/trusted_root.json | 114 + .../github.com/sourcegraph/conc/.golangci.yml | 11 + vendor/github.com/sourcegraph/conc/LICENSE | 21 + vendor/github.com/sourcegraph/conc/README.md | 464 + .../internal/multierror/multierror_go119.go | 10 + .../internal/multierror/multierror_go120.go | 10 + .../github.com/sourcegraph/conc/iter/iter.go | 85 + .../github.com/sourcegraph/conc/iter/map.go | 65 + .../sourcegraph/conc/panics/panics.go | 102 + .../github.com/sourcegraph/conc/panics/try.go | 11 + .../github.com/sourcegraph/conc/waitgroup.go | 52 + vendor/github.com/spf13/afero/const_bsds.go | 4 +- .../github.com/spf13/afero/const_win_unix.go | 4 +- vendor/github.com/spf13/afero/memmap.go | 65 +- vendor/github.com/spf13/cobra/.golangci.yml | 8 +- vendor/github.com/spf13/cobra/README.md | 8 +- vendor/github.com/spf13/cobra/active_help.go | 10 +- vendor/github.com/spf13/cobra/active_help.md | 157 - .../spf13/cobra/bash_completions.go | 2 +- .../spf13/cobra/bash_completions.md | 93 - .../spf13/cobra/bash_completionsV2.go | 2 +- vendor/github.com/spf13/cobra/cobra.go | 13 +- vendor/github.com/spf13/cobra/command.go | 69 +- vendor/github.com/spf13/cobra/completions.go | 29 +- .../spf13/cobra/fish_completions.go | 2 +- .../spf13/cobra/fish_completions.md | 4 - vendor/github.com/spf13/cobra/flag_groups.go | 68 +- .../spf13/cobra/powershell_completions.go | 6 +- .../spf13/cobra/powershell_completions.md | 3 - .../spf13/cobra/projects_using_cobra.md | 64 - .../spf13/cobra/shell_completions.md | 576 -- vendor/github.com/spf13/cobra/user_guide.md | 726 -- .../github.com/spf13/cobra/zsh_completions.md | 48 - .../spf13/jwalterweatherman/README.md | 148 - .../jwalterweatherman/default_notepad.go | 111 - .../spf13/jwalterweatherman/log_counter.go | 46 - .../spf13/jwalterweatherman/notepad.go | 225 - vendor/github.com/spf13/viper/.editorconfig | 3 + vendor/github.com/spf13/viper/.envrc | 4 + vendor/github.com/spf13/viper/.gitignore | 3 + vendor/github.com/spf13/viper/.yamlignore | 2 + vendor/github.com/spf13/viper/.yamllint.yaml | 6 + vendor/github.com/spf13/viper/Makefile | 45 +- vendor/github.com/spf13/viper/README.md | 61 +- .../spf13/viper/experimental_logger.go | 11 - vendor/github.com/spf13/viper/flags.go | 2 +- vendor/github.com/spf13/viper/flake.lock | 255 + vendor/github.com/spf13/viper/flake.nix | 56 + vendor/github.com/spf13/viper/fs.go | 65 - .../spf13/viper/internal/encoding/decoder.go | 6 +- .../viper/internal/encoding/dotenv/codec.go | 6 +- .../internal/encoding/dotenv/map_utils.go | 16 +- .../spf13/viper/internal/encoding/encoder.go | 6 +- .../viper/internal/encoding/hcl/codec.go | 4 +- .../viper/internal/encoding/ini/codec.go | 6 +- .../viper/internal/encoding/ini/map_utils.go | 24 +- .../internal/encoding/javaproperties/codec.go | 6 +- .../encoding/javaproperties/map_utils.go | 24 +- .../viper/internal/encoding/json/codec.go | 4 +- .../viper/internal/encoding/toml/codec.go | 4 +- .../viper/internal/encoding/yaml/codec.go | 4 +- vendor/github.com/spf13/viper/logger.go | 57 +- vendor/github.com/spf13/viper/util.go | 45 +- vendor/github.com/spf13/viper/viper.go | 243 +- vendor/github.com/spf13/viper/viper_go1_15.go | 3 +- vendor/github.com/spf13/viper/viper_go1_16.go | 28 +- vendor/github.com/spf13/viper/watch.go | 1 - .../spf13/viper/watch_unsupported.go | 1 - .../github.com/subosito/gotenv/CHANGELOG.md | 37 + vendor/github.com/subosito/gotenv/gotenv.go | 50 +- .../theupdateframework/go-tuf/.golangci.yml | 6 - .../theupdateframework/go-tuf/README.md | 9 +- .../theupdateframework/go-tuf/data/types.go | 9 +- .../theupdateframework/go-tuf/local_store.go | 2 +- .../pkg/deprecated/set_ecdsa/set_ecdsa.go | 23 - .../go-tuf/pkg/keys/ecdsa.go | 2 + .../theupdateframework/go-tuf/repo.go | 41 +- .../go-tuf/requirements-test.txt | 8 +- .../theupdateframework/go-tuf/sign/sign.go | 61 +- vendor/github.com/tinylib/msgp/LICENSE | 8 + .../tinylib/msgp/msgp/advise_linux.go | 25 + .../tinylib/msgp/msgp/advise_other.go | 18 + .../github.com/tinylib/msgp/msgp/circular.go | 39 + vendor/github.com/tinylib/msgp/msgp/defs.go | 147 + vendor/github.com/tinylib/msgp/msgp/edit.go | 242 + vendor/github.com/tinylib/msgp/msgp/elsize.go | 128 + .../tinylib/msgp/msgp/elsize_default.go | 21 + .../tinylib/msgp/msgp/elsize_tinygo.go | 13 + vendor/github.com/tinylib/msgp/msgp/errors.go | 359 + .../tinylib/msgp/msgp/errors_default.go | 25 + .../tinylib/msgp/msgp/errors_tinygo.go | 42 + .../github.com/tinylib/msgp/msgp/extension.go | 550 + vendor/github.com/tinylib/msgp/msgp/file.go | 93 + .../github.com/tinylib/msgp/msgp/file_port.go | 48 + .../github.com/tinylib/msgp/msgp/integers.go | 174 + vendor/github.com/tinylib/msgp/msgp/json.go | 568 ++ .../tinylib/msgp/msgp/json_bytes.go | 341 + vendor/github.com/tinylib/msgp/msgp/number.go | 266 + vendor/github.com/tinylib/msgp/msgp/purego.go | 16 + vendor/github.com/tinylib/msgp/msgp/read.go | 1374 +++ .../tinylib/msgp/msgp/read_bytes.go | 1303 +++ vendor/github.com/tinylib/msgp/msgp/size.go | 39 + vendor/github.com/tinylib/msgp/msgp/unsafe.go | 37 + vendor/github.com/tinylib/msgp/msgp/write.go | 813 ++ .../tinylib/msgp/msgp/write_bytes.go | 436 + vendor/github.com/tjfoc/gmsm/sm3/ifile | 1 + vendor/github.com/tjfoc/gmsm/sm3/sm3.go | 25 +- vendor/github.com/ulikunitz/xz/.gitignore | 3 + vendor/github.com/ulikunitz/xz/LICENSE | 2 +- vendor/github.com/ulikunitz/xz/README.md | 4 + vendor/github.com/ulikunitz/xz/TODO.md | 11 +- vendor/github.com/ulikunitz/xz/bits.go | 2 +- vendor/github.com/ulikunitz/xz/crc.go | 2 +- vendor/github.com/ulikunitz/xz/format.go | 2 +- .../ulikunitz/xz/internal/hash/cyclic_poly.go | 2 +- .../ulikunitz/xz/internal/hash/doc.go | 2 +- .../ulikunitz/xz/internal/hash/rabin_karp.go | 2 +- .../ulikunitz/xz/internal/hash/roller.go | 2 +- .../ulikunitz/xz/internal/xlog/xlog.go | 5 +- .../github.com/ulikunitz/xz/lzma/bintree.go | 2 +- vendor/github.com/ulikunitz/xz/lzma/bitops.go | 2 +- .../github.com/ulikunitz/xz/lzma/breader.go | 2 +- vendor/github.com/ulikunitz/xz/lzma/buffer.go | 2 +- .../ulikunitz/xz/lzma/bytewriter.go | 2 +- .../github.com/ulikunitz/xz/lzma/decoder.go | 2 +- .../ulikunitz/xz/lzma/decoderdict.go | 2 +- .../ulikunitz/xz/lzma/directcodec.go | 2 +- .../github.com/ulikunitz/xz/lzma/distcodec.go | 2 +- .../github.com/ulikunitz/xz/lzma/encoder.go | 2 +- .../ulikunitz/xz/lzma/encoderdict.go | 2 +- .../github.com/ulikunitz/xz/lzma/hashtable.go | 2 +- vendor/github.com/ulikunitz/xz/lzma/header.go | 2 +- .../github.com/ulikunitz/xz/lzma/header2.go | 2 +- .../ulikunitz/xz/lzma/lengthcodec.go | 5 +- .../ulikunitz/xz/lzma/literalcodec.go | 2 +- .../ulikunitz/xz/lzma/matchalgorithm.go | 2 +- .../github.com/ulikunitz/xz/lzma/operation.go | 2 +- vendor/github.com/ulikunitz/xz/lzma/prob.go | 2 +- .../ulikunitz/xz/lzma/properties.go | 2 +- .../ulikunitz/xz/lzma/rangecodec.go | 2 +- vendor/github.com/ulikunitz/xz/lzma/reader.go | 4 +- .../github.com/ulikunitz/xz/lzma/reader2.go | 2 +- vendor/github.com/ulikunitz/xz/lzma/state.go | 2 +- .../ulikunitz/xz/lzma/treecodecs.go | 2 +- vendor/github.com/ulikunitz/xz/lzma/writer.go | 2 +- .../github.com/ulikunitz/xz/lzma/writer2.go | 2 +- vendor/github.com/ulikunitz/xz/lzmafilter.go | 2 +- vendor/github.com/ulikunitz/xz/none-check.go | 2 +- vendor/github.com/ulikunitz/xz/reader.go | 2 +- vendor/github.com/ulikunitz/xz/writer.go | 2 +- .../vbatts/tar-split/archive/tar/reader.go | 7 +- .../xanzy/go-gitlab/CONTRIBUTING.md | 35 +- vendor/github.com/xanzy/go-gitlab/README.md | 1 + .../github.com/xanzy/go-gitlab/appearance.go | 110 + vendor/github.com/xanzy/go-gitlab/commits.go | 6 +- .../github.com/xanzy/go-gitlab/deployments.go | 18 + .../github.com/xanzy/go-gitlab/discussions.go | 37 +- .../xanzy/go-gitlab/event_webhook_types.go | 7 + vendor/github.com/xanzy/go-gitlab/gitlab.go | 240 +- .../xanzy/go-gitlab/group_access_tokens.go | 25 + .../xanzy/go-gitlab/group_badges.go | 9 +- .../xanzy/go-gitlab/group_epic_boards.go | 104 + .../go-gitlab/group_protected_environments.go | 278 + .../group_repository_storage_move.go | 195 + vendor/github.com/xanzy/go-gitlab/groups.go | 37 +- vendor/github.com/xanzy/go-gitlab/issues.go | 2 + .../xanzy/go-gitlab/job_token_scope.go | 186 + vendor/github.com/xanzy/go-gitlab/jobs.go | 19 + vendor/github.com/xanzy/go-gitlab/keys.go | 31 + .../xanzy/go-gitlab/merge_requests.go | 225 +- .../xanzy/go-gitlab/merge_trains.go | 170 + .../github.com/xanzy/go-gitlab/milestones.go | 1 + .../xanzy/go-gitlab/notifications.go | 64 +- .../xanzy/go-gitlab/personal_access_tokens.go | 21 + .../github.com/xanzy/go-gitlab/pipelines.go | 3 +- .../xanzy/go-gitlab/project_access_tokens.go | 25 + .../project_repository_storage_move.go | 199 + vendor/github.com/xanzy/go-gitlab/projects.go | 41 +- .../xanzy/go-gitlab/protected_environments.go | 67 + .../xanzy/go-gitlab/protected_tags.go | 1 + vendor/github.com/xanzy/go-gitlab/releases.go | 25 + .../xanzy/go-gitlab/repositories.go | 1 + .../go-gitlab/resource_iteration_events.go | 122 + vendor/github.com/xanzy/go-gitlab/services.go | 183 +- vendor/github.com/xanzy/go-gitlab/settings.go | 6 +- .../snippet_repository_storage_move.go | 203 + vendor/github.com/xanzy/go-gitlab/snippets.go | 31 + .../github.com/xanzy/go-gitlab/time_stats.go | 1 + vendor/github.com/xanzy/go-gitlab/todos.go | 2 +- vendor/github.com/xanzy/go-gitlab/types.go | 5 +- vendor/github.com/xanzy/go-gitlab/users.go | 135 +- .../bson/bsoncodec/array_codec.go | 10 +- .../mongo-driver/bson/bsoncodec/bsoncodec.go | 156 +- .../bson/bsoncodec/byte_slice_codec.go | 20 +- .../bson/bsoncodec/default_value_decoders.go | 146 +- .../bson/bsoncodec/default_value_encoders.go | 178 +- .../mongo-driver/bson/bsoncodec/doc.go | 73 +- .../bson/bsoncodec/empty_interface_codec.go | 16 +- .../mongo-driver/bson/bsoncodec/map_codec.go | 36 +- .../bson/bsoncodec/pointer_codec.go | 6 + .../mongo-driver/bson/bsoncodec/registry.go | 456 +- .../bson/bsoncodec/slice_codec.go | 30 +- .../bson/bsoncodec/string_codec.go | 21 +- .../bson/bsoncodec/struct_codec.go | 157 +- .../bson/bsoncodec/struct_tag_parser.go | 11 +- .../mongo-driver/bson/bsoncodec/time_codec.go | 16 +- .../mongo-driver/bson/bsoncodec/uint_codec.go | 13 +- .../bsonoptions/byte_slice_codec_options.go | 11 + .../empty_interface_codec_options.go | 11 + .../bson/bsonoptions/map_codec_options.go | 15 + .../bson/bsonoptions/slice_codec_options.go | 11 + .../bson/bsonoptions/string_codec_options.go | 11 + .../bson/bsonoptions/struct_codec_options.go | 20 + .../bson/bsonoptions/time_codec_options.go | 11 + .../bson/bsonoptions/uint_codec_options.go | 11 + .../mongo-driver/bson/bsonrw/copier.go | 43 + .../bson/bsonrw/extjson_reader.go | 8 + .../bson/bsonrw/extjson_writer.go | 23 +- .../mongo-driver/bson/bsonrw/reader.go | 2 + .../mongo-driver/bson/bsonrw/value_reader.go | 8 + .../mongo-driver/bson/bsonrw/value_writer.go | 10 + .../mongo-driver/bson/bsonrw/writer.go | 9 + .../mongo-driver/bson/bsontype/bsontype.go | 20 +- .../mongo-driver/bson/decoder.go | 79 +- .../go.mongodb.org/mongo-driver/bson/doc.go | 5 +- .../mongo-driver/bson/encoder.go | 110 +- .../mongo-driver/bson/marshal.go | 193 +- .../mongo-driver/bson/primitive/decimal.go | 14 + .../mongo-driver/bson/primitive/objectid.go | 8 +- .../mongo-driver/bson/primitive/primitive.go | 46 +- .../mongo-driver/bson/primitive_codecs.go | 40 +- .../go.mongodb.org/mongo-driver/bson/raw.go | 23 +- .../mongo-driver/bson/raw_element.go | 7 +- .../mongo-driver/bson/raw_value.go | 19 +- .../mongo-driver/bson/registry.go | 15 +- .../go.mongodb.org/mongo-driver/bson/types.go | 15 +- .../mongo-driver/bson/unmarshal.go | 92 +- .../mongo-driver/x/bsonx/bsoncore/array.go | 10 +- .../mongo-driver/x/bsonx/bsoncore/bsoncore.go | 22 +- .../mongo-driver/x/bsonx/bsoncore/doc.go | 29 + .../mongo-driver/x/bsonx/bsoncore/document.go | 10 +- .../mongo-driver/x/bsonx/bsoncore/element.go | 2 +- .../mongo-driver/x/bsonx/bsoncore/value.go | 23 +- vendor/go.opentelemetry.io/otel/.gitignore | 1 + vendor/go.opentelemetry.io/otel/.golangci.yml | 79 +- vendor/go.opentelemetry.io/otel/CHANGELOG.md | 172 +- vendor/go.opentelemetry.io/otel/CODEOWNERS | 2 +- .../go.opentelemetry.io/otel/CONTRIBUTING.md | 90 +- vendor/go.opentelemetry.io/otel/Makefile | 62 +- vendor/go.opentelemetry.io/otel/README.md | 42 +- vendor/go.opentelemetry.io/otel/RELEASING.md | 31 +- .../otel/attribute/filter.go | 60 + .../go.opentelemetry.io/otel/attribute/set.go | 7 - .../otel/baggage/baggage.go | 14 +- .../go.opentelemetry.io/otel/internal/gen.go | 29 + .../otel/internal/global/handler.go | 7 +- .../otel/internal/global/internal_logging.go | 7 +- .../otel/metric/instrument.go | 2 + .../go.opentelemetry.io/otel/metric/meter.go | 2 + .../go.opentelemetry.io/otel/requirements.txt | 2 +- vendor/go.opentelemetry.io/otel/version.go | 2 +- vendor/go.opentelemetry.io/otel/versions.yaml | 18 +- vendor/go.step.sm/crypto/jose/parse.go | 2 +- vendor/go.step.sm/crypto/pemutil/pem.go | 42 +- vendor/go.uber.org/atomic/CHANGELOG.md | 10 + vendor/go.uber.org/atomic/bool.go | 2 +- vendor/go.uber.org/atomic/duration.go | 2 +- vendor/go.uber.org/atomic/error.go | 14 +- vendor/go.uber.org/atomic/float32.go | 2 +- vendor/go.uber.org/atomic/float64.go | 2 +- vendor/go.uber.org/atomic/int32.go | 2 +- vendor/go.uber.org/atomic/int64.go | 2 +- vendor/go.uber.org/atomic/pointer_go118.go | 41 +- .../atomic/pointer_go118_pre119.go | 60 + vendor/go.uber.org/atomic/string.go | 23 +- vendor/go.uber.org/atomic/string_ext.go | 15 +- vendor/go.uber.org/atomic/time.go | 2 +- vendor/go.uber.org/atomic/uint32.go | 2 +- vendor/go.uber.org/atomic/uint64.go | 2 +- vendor/go.uber.org/atomic/uintptr.go | 2 +- vendor/go.uber.org/zap/.golangci.yml | 77 + vendor/go.uber.org/zap/CHANGELOG.md | 242 +- vendor/go.uber.org/zap/Makefile | 87 +- vendor/go.uber.org/zap/README.md | 62 +- vendor/go.uber.org/zap/array.go | 127 + vendor/go.uber.org/zap/array_go118.go | 156 - vendor/go.uber.org/zap/buffer/buffer.go | 5 + vendor/go.uber.org/zap/buffer/pool.go | 20 +- vendor/go.uber.org/zap/config.go | 84 +- vendor/go.uber.org/zap/error.go | 14 +- vendor/go.uber.org/zap/field.go | 194 +- vendor/go.uber.org/zap/http_handler.go | 19 +- .../go.uber.org/zap/internal/level_enabler.go | 2 + vendor/go.uber.org/zap/internal/pool/pool.go | 58 + .../stacktrace/stack.go} | 81 +- vendor/go.uber.org/zap/level.go | 9 +- vendor/go.uber.org/zap/logger.go | 48 +- vendor/go.uber.org/zap/sink.go | 5 +- vendor/go.uber.org/zap/sugar.go | 69 +- vendor/go.uber.org/zap/writer.go | 12 +- .../zap/zapcore/console_encoder.go | 14 +- vendor/go.uber.org/zap/zapcore/core.go | 6 +- vendor/go.uber.org/zap/zapcore/entry.go | 22 +- vendor/go.uber.org/zap/zapcore/error.go | 14 +- .../go.uber.org/zap/zapcore/json_encoder.go | 155 +- vendor/go.uber.org/zap/zapcore/lazy_with.go | 54 + vendor/go.uber.org/zap/zapcore/sampler.go | 9 +- vendor/go4.org/intern/LICENSE | 29 + vendor/go4.org/intern/README.md | 19 + vendor/go4.org/intern/intern.go | 183 + .../unsafe/assume-no-moving-gc/LICENSE | 29 + .../unsafe/assume-no-moving-gc/README.md | 13 + .../assume-no-moving-gc.go | 32 + .../unsafe/assume-no-moving-gc/check.go | 36 + vendor/golang.org/x/exp/slices/cmp.go | 44 + vendor/golang.org/x/exp/slices/slices.go | 381 +- vendor/golang.org/x/exp/slices/sort.go | 125 +- .../slices/{zsortfunc.go => zsortanyfunc.go} | 154 +- .../golang.org/x/exp/slices/zsortordered.go | 34 +- vendor/golang.org/x/exp/slog/attr.go | 102 + vendor/golang.org/x/exp/slog/doc.go | 316 + vendor/golang.org/x/exp/slog/handler.go | 559 ++ .../x/exp/slog/internal/buffer/buffer.go | 84 + .../x/exp/slog/internal/ignorepc.go | 9 + vendor/golang.org/x/exp/slog/json_handler.go | 336 + vendor/golang.org/x/exp/slog/level.go | 201 + vendor/golang.org/x/exp/slog/logger.go | 343 + vendor/golang.org/x/exp/slog/noplog.bench | 36 + vendor/golang.org/x/exp/slog/record.go | 207 + vendor/golang.org/x/exp/slog/text_handler.go | 161 + vendor/golang.org/x/exp/slog/value.go | 456 + vendor/golang.org/x/exp/slog/value_119.go | 53 + vendor/golang.org/x/exp/slog/value_120.go | 39 + .../x/mod/internal/lazyregexp/lazyre.go | 2 +- vendor/golang.org/x/mod/modfile/read.go | 2 +- vendor/golang.org/x/mod/modfile/rule.go | 24 +- vendor/golang.org/x/mod/modfile/work.go | 4 +- vendor/golang.org/x/mod/module/module.go | 30 +- vendor/golang.org/x/mod/module/pseudo.go | 2 +- vendor/golang.org/x/mod/semver/semver.go | 6 +- vendor/golang.org/x/mod/sumdb/note/note.go | 38 +- vendor/golang.org/x/oauth2/deviceauth.go | 198 + .../x/oauth2/google/appengine_gen1.go | 1 - .../x/oauth2/google/appengine_gen2_flex.go | 1 - vendor/golang.org/x/oauth2/google/default.go | 31 +- vendor/golang.org/x/oauth2/google/google.go | 46 +- .../google/internal/externalaccount/aws.go | 47 +- .../externalaccount/basecredentials.go | 45 +- .../externalaccount/executablecredsource.go | 4 + .../externalaccount/filecredsource.go | 4 + .../google/internal/externalaccount/header.go | 64 + .../internal/externalaccount/urlcredsource.go | 4 + .../externalaccountauthorizeduser.go | 114 + .../clientauth.go | 8 +- .../sts_exchange.go | 42 +- .../x/oauth2/internal/client_appengine.go | 1 - vendor/golang.org/x/oauth2/internal/token.go | 70 +- vendor/golang.org/x/oauth2/oauth2.go | 33 +- vendor/golang.org/x/oauth2/pkce.go | 68 + vendor/golang.org/x/oauth2/token.go | 2 +- vendor/golang.org/x/sync/errgroup/go120.go | 1 - .../golang.org/x/sync/errgroup/pre_go120.go | 1 - .../golang.org/x/sys/windows/registry/key.go | 206 + .../x/sys/windows/registry/mksyscall.go | 10 + .../x/sys/windows/registry/syscall.go | 33 + .../x/sys/windows/registry/value.go | 387 + .../sys/windows/registry/zsyscall_windows.go | 117 + .../x/tools/cmd/stringer/stringer.go | 5 +- .../x/tools/go/ast/inspector/inspector.go | 4 +- .../tools/go/internal/packagesdriver/sizes.go | 11 +- vendor/golang.org/x/tools/go/packages/doc.go | 2 +- .../golang.org/x/tools/go/packages/golist.go | 19 +- .../x/tools/go/packages/packages.go | 16 +- .../x/tools/go/types/objectpath/objectpath.go | 827 ++ vendor/golang.org/x/tools/imports/forward.go | 4 +- .../x/tools/internal/event/tag/tag.go | 2 +- .../x/tools/internal/fastwalk/fastwalk.go | 16 +- .../internal/fastwalk/fastwalk_portable.go | 11 +- .../x/tools/internal/gcimporter/gcimporter.go | 3 +- .../x/tools/internal/gcimporter/iexport.go | 175 +- .../x/tools/internal/gcimporter/iimport.go | 188 +- .../x/tools/internal/gocommand/invoke.go | 4 +- .../x/tools/internal/gopathwalk/walk.go | 20 +- .../x/tools/internal/imports/fix.go | 7 +- .../x/tools/internal/imports/mod.go | 13 +- .../x/tools/internal/imports/mod_cache.go | 2 +- .../x/tools/internal/imports/zstdlib.go | 230 + .../x/tools/internal/typeparams/common.go | 26 + .../x/tools/internal/typeparams/coretype.go | 8 +- .../x/tools/internal/typeparams/termlist.go | 2 +- .../internal/typeparams/typeparams_go117.go | 2 +- .../internal/typeparams/typeparams_go118.go | 2 +- .../x/tools/internal/typeparams/typeterm.go | 9 +- .../internal/typesinternal/objectpath.go | 24 + vendor/golang.org/x/xerrors/LICENSE | 27 + vendor/golang.org/x/xerrors/PATENTS | 22 + vendor/golang.org/x/xerrors/README | 2 + vendor/golang.org/x/xerrors/adaptor.go | 193 + vendor/golang.org/x/xerrors/codereview.cfg | 1 + vendor/golang.org/x/xerrors/doc.go | 23 + vendor/golang.org/x/xerrors/errors.go | 33 + vendor/golang.org/x/xerrors/fmt.go | 190 + vendor/golang.org/x/xerrors/format.go | 34 + vendor/golang.org/x/xerrors/frame.go | 56 + .../golang.org/x/xerrors/internal/internal.go | 8 + vendor/golang.org/x/xerrors/wrap.go | 112 + .../google.golang.org/api/idtoken/validate.go | 19 +- vendor/google.golang.org/api/internal/cba.go | 40 +- .../google.golang.org/api/internal/creds.go | 5 +- vendor/google.golang.org/api/internal/s2a.go | 2 +- .../api/internal/settings.go | 17 + .../google.golang.org/api/internal/version.go | 2 +- .../option/internaloption/internaloption.go | 13 + .../api/transport/http/dial.go | 17 +- .../api/transport/http/dial_appengine.go | 21 - .../google.golang.org/appengine/.travis.yml | 18 - .../appengine/CONTRIBUTING.md | 6 +- vendor/google.golang.org/appengine/README.md | 6 +- .../google.golang.org/appengine/appengine.go | 23 +- .../appengine/appengine_vm.go | 12 +- .../google.golang.org/appengine/identity.go | 3 +- .../appengine/internal/api.go | 347 +- .../appengine/internal/api_classic.go | 29 +- .../appengine/internal/api_common.go | 50 +- .../appengine/internal/identity.go | 7 +- .../appengine/internal/identity_classic.go | 23 +- .../appengine/internal/identity_flex.go | 1 + .../appengine/internal/identity_vm.go | 20 +- .../appengine/internal/main.go | 1 + .../appengine/internal/main_vm.go | 3 +- .../internal/socket/socket_service.pb.go | 2822 ------ .../internal/socket/socket_service.proto | 460 - .../appengine/internal/transaction.go | 10 +- .../google.golang.org/appengine/namespace.go | 3 +- .../google.golang.org/appengine/socket/doc.go | 10 - .../appengine/socket/socket_classic.go | 290 - .../appengine/socket/socket_vm.go | 64 - vendor/google.golang.org/appengine/timeout.go | 2 +- .../appengine/travis_install.sh | 18 - .../appengine/travis_test.sh | 12 - .../appengine/urlfetch/urlfetch.go | 9 +- vendor/google.golang.org/grpc/README.md | 60 +- .../grpc/attributes/attributes.go | 59 +- .../grpc/balancer/balancer.go | 62 +- .../grpc/balancer/base/balancer.go | 22 +- .../grpc/balancer_conn_wrappers.go | 75 +- .../grpc_binarylog_v1/binarylog.pb.go | 2 +- vendor/google.golang.org/grpc/call.go | 11 +- vendor/google.golang.org/grpc/clientconn.go | 248 +- vendor/google.golang.org/grpc/codec.go | 8 +- vendor/google.golang.org/grpc/dialoptions.go | 42 +- .../grpc/encoding/encoding.go | 17 +- .../grpc/encoding/proto/proto.go | 4 +- .../grpc/grpclog/component.go | 40 +- .../google.golang.org/grpc/grpclog/grpclog.go | 30 +- .../google.golang.org/grpc/grpclog/logger.go | 30 +- .../grpc/grpclog/loggerv2.go | 56 +- vendor/google.golang.org/grpc/interceptor.go | 12 +- .../grpc/internal/backoff/backoff.go | 36 + .../balancer/gracefulswitch/gracefulswitch.go | 59 +- .../grpc/internal/balancerload/load.go | 4 +- .../grpc/internal/binarylog/method_logger.go | 4 +- .../grpc/internal/buffer/unbounded.go | 18 +- .../grpc/internal/channelz/funcs.go | 69 +- .../grpc/internal/channelz/logging.go | 12 +- .../grpc/internal/channelz/types.go | 5 + .../grpc/internal/channelz/util_linux.go | 2 +- .../grpc/internal/channelz/util_nonlinux.go | 2 +- .../grpc/internal/credentials/credentials.go | 8 +- .../grpc/internal/envconfig/envconfig.go | 12 +- .../grpc/internal/grpclog/grpclog.go | 40 +- .../grpc/internal/grpclog/prefixLogger.go | 8 +- .../grpc/internal/grpcrand/grpcrand.go | 7 + .../internal/grpcsync/callback_serializer.go | 54 +- .../grpc/internal/grpcsync/pubsub.go | 121 + .../grpc/{ => internal/idle}/idle.go | 188 +- .../grpc/internal/internal.go | 51 +- .../grpc/internal/metadata/metadata.go | 2 +- .../grpc/internal/pretty/pretty.go | 2 +- .../grpc/internal/resolver/config_selector.go | 4 +- .../internal/resolver/dns/dns_resolver.go | 74 +- .../grpc/internal/status/status.go | 36 +- .../grpc/internal/transport/controlbuf.go | 16 +- .../grpc/internal/transport/handler_server.go | 13 +- .../grpc/internal/transport/http2_client.go | 56 +- .../grpc/internal/transport/http2_server.go | 22 +- .../grpc/internal/transport/http_util.go | 77 +- .../grpc/internal/transport/transport.go | 19 +- .../google.golang.org/grpc/picker_wrapper.go | 34 +- vendor/google.golang.org/grpc/pickfirst.go | 88 +- vendor/google.golang.org/grpc/preloader.go | 2 +- vendor/google.golang.org/grpc/resolver/map.go | 10 +- .../grpc/resolver/resolver.go | 84 +- .../grpc/resolver_conn_wrapper.go | 10 +- vendor/google.golang.org/grpc/rpc_util.go | 44 +- vendor/google.golang.org/grpc/server.go | 231 +- .../grpc/shared_buffer_pool.go | 154 + vendor/google.golang.org/grpc/stats/stats.go | 14 +- .../google.golang.org/grpc/status/status.go | 14 +- vendor/google.golang.org/grpc/stream.go | 130 +- vendor/google.golang.org/grpc/tap/tap.go | 6 + vendor/google.golang.org/grpc/trace.go | 6 +- vendor/google.golang.org/grpc/version.go | 2 +- vendor/google.golang.org/grpc/vet.sh | 10 +- .../protobuf/encoding/protojson/encode.go | 14 +- .../protobuf/encoding/prototext/encode.go | 14 +- .../protobuf/internal/encoding/json/encode.go | 10 +- .../protobuf/internal/encoding/text/encode.go | 10 +- .../protobuf/internal/genid/descriptor_gen.go | 48 + .../protobuf/internal/genid/type_gen.go | 6 + .../protobuf/internal/order/order.go | 2 +- .../protobuf/internal/version/version.go | 2 +- .../google.golang.org/protobuf/proto/size.go | 10 +- .../reflect/protoreflect/source_gen.go | 27 + .../types/descriptorpb/descriptor.pb.go | 1011 +- .../protobuf/types/known/anypb/any.pb.go | 70 +- .../protobuf/types/known/emptypb/empty.pb.go | 166 - .../types/known/structpb/struct.pb.go | 2 +- .../types/known/timestamppb/timestamp.pb.go | 2 +- .../gopkg.in/DataDog/dd-trace-go.v1/LICENSE | 234 + .../dd-trace-go.v1/LICENSE-3rdparty.csv | 4 + .../DataDog/dd-trace-go.v1/LICENSE-APACHE | 200 + .../DataDog/dd-trace-go.v1/LICENSE-BSD3 | 24 + vendor/gopkg.in/DataDog/dd-trace-go.v1/NOTICE | 4 + .../datastreams/options/options.go | 10 + .../DataDog/dd-trace-go.v1/ddtrace/ddtrace.go | 158 + .../dd-trace-go.v1/ddtrace/ext/app_types.go | 81 + .../DataDog/dd-trace-go.v1/ddtrace/ext/db.go | 87 + .../dd-trace-go.v1/ddtrace/ext/messaging.go | 25 + .../dd-trace-go.v1/ddtrace/ext/peer.go | 20 + .../dd-trace-go.v1/ddtrace/ext/priority.go | 27 + .../DataDog/dd-trace-go.v1/ddtrace/ext/rpc.go | 34 + .../dd-trace-go.v1/ddtrace/ext/span_kind.go | 32 + .../dd-trace-go.v1/ddtrace/ext/system.go | 12 + .../dd-trace-go.v1/ddtrace/ext/tags.go | 120 + .../ddtrace/internal/globaltracer.go | 104 + .../ddtrace/tracer/abandonedspans.go | 300 + .../dd-trace-go.v1/ddtrace/tracer/context.go | 59 + .../ddtrace/tracer/data_streams.go | 64 + .../dd-trace-go.v1/ddtrace/tracer/doc.go | 110 + .../dd-trace-go.v1/ddtrace/tracer/log.go | 136 + .../dd-trace-go.v1/ddtrace/tracer/metrics.go | 101 + .../dd-trace-go.v1/ddtrace/tracer/option.go | 1292 +++ .../dd-trace-go.v1/ddtrace/tracer/payload.go | 153 + .../ddtrace/tracer/propagating_tags.go | 68 + .../ddtrace/tracer/propagator.go | 57 + .../dd-trace-go.v1/ddtrace/tracer/rand.go | 56 + .../ddtrace/tracer/rules_sampler.go | 593 ++ .../dd-trace-go.v1/ddtrace/tracer/sampler.go | 150 + .../dd-trace-go.v1/ddtrace/tracer/span.go | 735 ++ .../ddtrace/tracer/span_msgp.go | 453 + .../ddtrace/tracer/spancontext.go | 559 ++ .../ddtrace/tracer/sqlcomment.go | 300 + .../dd-trace-go.v1/ddtrace/tracer/stats.go | 351 + .../ddtrace/tracer/stats_payload.go | 56 + .../ddtrace/tracer/stats_payload_msgp.go | 450 + .../ddtrace/tracer/telemetry.go | 101 + .../dd-trace-go.v1/ddtrace/tracer/textmap.go | 1037 ++ .../dd-trace-go.v1/ddtrace/tracer/time.go | 17 + .../ddtrace/tracer/time_windows.go | 48 + .../dd-trace-go.v1/ddtrace/tracer/tracer.go | 716 ++ .../ddtrace/tracer/transport.go | 214 + .../dd-trace-go.v1/ddtrace/tracer/util.go | 124 + .../dd-trace-go.v1/ddtrace/tracer/writer.go | 340 + .../internal/active_span_key.go | 11 + .../DataDog/dd-trace-go.v1/internal/agent.go | 36 + .../dd-trace-go.v1/internal/appsec/appsec.go | 183 + .../internal/appsec/appsec_disabled.go | 38 + .../dd-trace-go.v1/internal/appsec/config.go | 189 + .../appsec/dyngo/instrumentation/common.go | 166 + .../dyngo/instrumentation/grpcsec/grpc.go | 209 + .../dyngo/instrumentation/grpcsec/tags.go | 36 + .../dyngo/instrumentation/httpsec/http.go | 337 + .../dyngo/instrumentation/httpsec/tags.go | 133 + .../instrumentation/sharedsec/actions.go | 135 + .../sharedsec/blocked-template.html | 1 + .../sharedsec/blocked-template.json | 1 + .../dyngo/instrumentation/sharedsec/shared.go | 80 + .../internal/appsec/dyngo/operation.go | 353 + .../dd-trace-go.v1/internal/appsec/limiter.go | 143 + .../internal/appsec/remoteconfig.go | 381 + .../dd-trace-go.v1/internal/appsec/rules.go | 17 + .../dd-trace-go.v1/internal/appsec/rules.json | 7079 +++++++++++++ .../internal/appsec/rules_manager.go | 147 + .../dd-trace-go.v1/internal/appsec/waf.go | 555 ++ .../dd-trace-go.v1/internal/container.go | 71 + .../internal/datastreams/pathway.go | 96 + .../internal/datastreams/payload.go | 84 + .../internal/datastreams/payload_msgp.go | 907 ++ .../internal/datastreams/processor.go | 472 + .../internal/datastreams/propagator.go | 87 + .../internal/datastreams/transport.go | 115 + .../DataDog/dd-trace-go.v1/internal/env.go | 94 + .../dd-trace-go.v1/internal/gitmetadata.go | 123 + .../internal/gitmetadatabinary.go | 41 + .../internal/gitmetadatabinary_legacy.go | 19 + .../internal/globalconfig/globalconfig.go | 95 + .../internal/hostname/azure/azure.go | 63 + .../internal/hostname/cachedfetch/fetcher.go | 86 + .../internal/hostname/ec2/ec2.go | 72 + .../internal/hostname/ecs/aws.go | 54 + .../internal/hostname/fqdn_nix.go | 28 + .../internal/hostname/fqdn_windows.go | 14 + .../internal/hostname/gce/gce.go | 120 + .../internal/hostname/httputils/helpers.go | 74 + .../internal/hostname/providers.go | 245 + .../internal/hostname/validate/validate.go | 57 + .../dd-trace-go.v1/internal/log/log.go | 243 + .../internal/namingschema/namingschema.go | 117 + .../internal/namingschema/op_cache.go | 46 + .../internal/namingschema/op_client_server.go | 85 + .../internal/namingschema/op_db.go | 50 + .../internal/namingschema/op_messaging.go | 84 + .../internal/namingschema/option.go | 20 + .../internal/namingschema/service_name.go | 50 + .../internal/normalizer/normalizer.go | 50 + .../dd-trace-go.v1/internal/osinfo/osinfo.go | 21 + .../internal/osinfo/osinfo_darwin.go | 24 + .../internal/osinfo/osinfo_default.go | 21 + .../internal/osinfo/osinfo_freebsd.go | 24 + .../internal/osinfo/osinfo_linux.go | 52 + .../internal/osinfo/osinfo_windows.go | 54 + .../internal/remoteconfig/config.go | 75 + .../internal/remoteconfig/remoteconfig.go | 414 + .../internal/remoteconfig/types.go | 83 + .../internal/samplernames/samplernames.go | 37 + .../DataDog/dd-trace-go.v1/internal/statsd.go | 17 + .../internal/telemetry/client.go | 580 ++ .../internal/telemetry/message.go | 257 + .../internal/telemetry/option.go | 142 + .../internal/telemetry/telemetry.go | 115 + .../internal/telemetry/utils.go | 50 + .../dd-trace-go.v1/internal/trace_context.go | 47 + .../internal/traceprof/endpoint_counter.go | 105 + .../internal/traceprof/profiler.go | 35 + .../internal/traceprof/traceprof.go | 21 + .../DataDog/dd-trace-go.v1/internal/utils.go | 64 + .../internal/version/version.go | 43 + .../go-jose/go-jose.v2/.gitcookies.sh.enc | 1 + vendor/gopkg.in/go-jose/go-jose.v2/.gitignore | 8 + .../gopkg.in/go-jose/go-jose.v2/.travis.yml | 45 + .../go-jose/go-jose.v2/CONTRIBUTING.md | 14 + vendor/gopkg.in/go-jose/go-jose.v2/LICENSE | 202 + vendor/gopkg.in/go-jose/go-jose.v2/README.md | 118 + .../gopkg.in/go-jose/go-jose.v2/asymmetric.go | 592 ++ .../go-jose/go-jose.v2/cipher/cbc_hmac.go | 196 + .../go-jose/go-jose.v2/cipher/concat_kdf.go | 75 + .../go-jose/go-jose.v2/cipher/ecdh_es.go | 86 + .../go-jose/go-jose.v2/cipher/key_wrap.go | 109 + vendor/gopkg.in/go-jose/go-jose.v2/crypter.go | 542 + vendor/gopkg.in/go-jose/go-jose.v2/doc.go | 27 + .../gopkg.in/go-jose/go-jose.v2/encoding.go | 185 + .../gopkg.in/go-jose/go-jose.v2/json/LICENSE | 27 + .../go-jose/go-jose.v2/json/README.md | 13 + .../go-jose/go-jose.v2/json/decode.go | 1217 +++ .../go-jose/go-jose.v2/json/encode.go | 1197 +++ .../go-jose/go-jose.v2/json/indent.go | 141 + .../go-jose/go-jose.v2/json/scanner.go | 623 ++ .../go-jose/go-jose.v2/json/stream.go | 485 + .../gopkg.in/go-jose/go-jose.v2/json/tags.go | 44 + vendor/gopkg.in/go-jose/go-jose.v2/jwe.go | 294 + vendor/gopkg.in/go-jose/go-jose.v2/jwk.go | 760 ++ vendor/gopkg.in/go-jose/go-jose.v2/jws.go | 366 + vendor/gopkg.in/go-jose/go-jose.v2/opaque.go | 144 + vendor/gopkg.in/go-jose/go-jose.v2/shared.go | 520 + vendor/gopkg.in/go-jose/go-jose.v2/signing.go | 441 + .../gopkg.in/go-jose/go-jose.v2/symmetric.go | 482 + vendor/inet.af/netaddr/.gitignore | 3 + vendor/inet.af/netaddr/.gitmodules | 3 + vendor/inet.af/netaddr/AUTHORS | 4 + vendor/inet.af/netaddr/LICENSE | 27 + vendor/inet.af/netaddr/README.md | 46 + vendor/inet.af/netaddr/fuzz.go | 203 + vendor/inet.af/netaddr/ipset.go | 497 + vendor/inet.af/netaddr/mask6.go | 141 + vendor/inet.af/netaddr/netaddr.go | 1919 ++++ vendor/inet.af/netaddr/uint128.go | 82 + .../admissionregistration/v1/generated.proto | 4 +- .../api/admissionregistration/v1/types.go | 4 +- .../v1/types_swagger_doc_generated.go | 4 +- .../v1alpha1/generated.pb.go | 541 +- .../v1alpha1/generated.proto | 92 +- .../admissionregistration/v1alpha1/types.go | 105 +- .../v1alpha1/types_swagger_doc_generated.go | 25 +- .../v1alpha1/zz_generated.deepcopy.go | 33 +- .../v1beta1/generated.pb.go | 5927 +++++++++-- .../v1beta1/generated.proto | 564 +- .../admissionregistration/v1beta1/register.go | 4 + .../admissionregistration/v1beta1/types.go | 594 +- .../v1beta1/types_swagger_doc_generated.go | 178 +- .../v1beta1/zz_generated.deepcopy.go | 448 +- .../zz_generated.prerelease-lifecycle.go | 72 + .../api/apidiscovery/v2beta1/generated.proto | 4 +- .../k8s.io/api/apidiscovery/v2beta1/types.go | 4 +- .../v1alpha1/generated.pb.go | 148 +- .../v1alpha1/generated.proto | 5 + .../api/apiserverinternal/v1alpha1/types.go | 5 + .../v1alpha1/types_swagger_doc_generated.go | 1 + .../v1alpha1/zz_generated.deepcopy.go | 5 + vendor/k8s.io/api/apps/v1/types.go | 3 +- .../api/authentication/v1/generated.pb.go | 511 +- .../api/authentication/v1/generated.proto | 20 + .../k8s.io/api/authentication/v1/register.go | 1 + vendor/k8s.io/api/authentication/v1/types.go | 25 + .../v1/types_swagger_doc_generated.go | 19 + .../v1/zz_generated.deepcopy.go | 44 + vendor/k8s.io/api/batch/v1/generated.pb.go | 398 +- vendor/k8s.io/api/batch/v1/generated.proto | 63 + vendor/k8s.io/api/batch/v1/types.go | 93 + .../batch/v1/types_swagger_doc_generated.go | 7 +- .../api/batch/v1/zz_generated.deepcopy.go | 25 + .../api/core/v1/annotation_key_constants.go | 6 +- vendor/k8s.io/api/core/v1/generated.pb.go | 3017 +++--- vendor/k8s.io/api/core/v1/generated.proto | 193 +- vendor/k8s.io/api/core/v1/types.go | 235 +- .../core/v1/types_swagger_doc_generated.go | 66 +- .../k8s.io/api/core/v1/well_known_labels.go | 4 + .../api/core/v1/zz_generated.deepcopy.go | 75 +- .../k8s.io/api/discovery/v1/generated.proto | 2 + vendor/k8s.io/api/discovery/v1/types.go | 2 + .../v1/types_swagger_doc_generated.go | 2 +- .../api/extensions/v1beta1/generated.pb.go | 610 +- .../api/extensions/v1beta1/generated.proto | 17 - vendor/k8s.io/api/extensions/v1beta1/types.go | 50 +- .../v1beta1/types_swagger_doc_generated.go | 10 - .../v1beta1/zz_generated.deepcopy.go | 24 - .../api/flowcontrol/v1alpha1/generated.pb.go | 477 +- .../api/flowcontrol/v1alpha1/generated.proto | 42 + .../k8s.io/api/flowcontrol/v1alpha1/types.go | 45 + .../v1alpha1/types_swagger_doc_generated.go | 11 + .../v1alpha1/zz_generated.deepcopy.go | 31 + .../api/flowcontrol/v1beta1/generated.pb.go | 476 +- .../api/flowcontrol/v1beta1/generated.proto | 42 + .../k8s.io/api/flowcontrol/v1beta1/types.go | 49 +- .../v1beta1/types_swagger_doc_generated.go | 11 + .../v1beta1/zz_generated.deepcopy.go | 31 + .../api/flowcontrol/v1beta2/generated.pb.go | 477 +- .../api/flowcontrol/v1beta2/generated.proto | 42 + .../k8s.io/api/flowcontrol/v1beta2/types.go | 49 +- .../v1beta2/types_swagger_doc_generated.go | 11 + .../v1beta2/zz_generated.deepcopy.go | 31 + .../api/flowcontrol/v1beta3/generated.pb.go | 475 +- .../api/flowcontrol/v1beta3/generated.proto | 46 +- .../k8s.io/api/flowcontrol/v1beta3/types.go | 53 +- .../v1beta3/types_swagger_doc_generated.go | 13 +- .../v1beta3/zz_generated.deepcopy.go | 31 + .../k8s.io/api/networking/v1/generated.pb.go | 443 +- .../k8s.io/api/networking/v1/generated.proto | 17 - vendor/k8s.io/api/networking/v1/types.go | 50 +- .../v1/types_swagger_doc_generated.go | 10 - .../networking/v1/zz_generated.deepcopy.go | 24 - vendor/k8s.io/api/rbac/v1/generated.proto | 2 + vendor/k8s.io/api/rbac/v1/types.go | 2 + .../rbac/v1/types_swagger_doc_generated.go | 4 +- .../k8s.io/apimachinery/pkg/api/errors/OWNERS | 1 - .../k8s.io/apimachinery/pkg/api/meta/help.go | 83 +- .../apimachinery/pkg/api/resource/OWNERS | 1 - .../pkg/apis/meta/v1/generated.proto | 2 - .../apimachinery/pkg/apis/meta/v1/types.go | 22 +- .../apis/meta/v1/unstructured/unstructured.go | 5 + .../meta/v1/unstructured/unstructured_list.go | 9 + .../k8s.io/apimachinery/pkg/runtime/codec.go | 1 - .../apimachinery/pkg/runtime/converter.go | 4 +- .../apimachinery/pkg/runtime/interfaces.go | 5 + .../pkg/runtime/schema/group_version.go | 2 +- .../k8s.io/apimachinery/pkg/runtime/splice.go | 76 + .../apimachinery/pkg/util/cache/expiring.go | 12 +- .../k8s.io/apimachinery/pkg/util/diff/diff.go | 37 +- .../k8s.io/apimachinery/pkg/util/dump/dump.go | 54 + .../pkg/util/httpstream/spdy/roundtripper.go | 4 +- .../apimachinery/pkg/util/intstr/intstr.go | 7 +- .../managedfields/internal/fieldmanager.go | 25 +- .../managedfields/internal/skipnonapplied.go | 14 +- .../managedfields/internal/structuredmerge.go | 3 + .../managedfields/internal/versioncheck.go | 52 + .../apimachinery/pkg/util/mergepatch/util.go | 4 +- .../k8s.io/apimachinery/pkg/util/net/util.go | 6 + .../apimachinery/pkg/util/runtime/runtime.go | 15 +- .../pkg/util/strategicpatch/patch.go | 63 +- .../apimachinery/pkg/util/version/version.go | 5 + .../k8s.io/apimachinery/pkg/util/wait/loop.go | 19 +- .../k8s.io/apimachinery/pkg/util/wait/poll.go | 28 +- .../v1alpha1/paramref.go | 27 +- .../v1alpha1/validatingadmissionpolicyspec.go | 14 + .../v1alpha1/variable.go | 48 + .../v1beta1/auditannotation.go | 48 + .../v1beta1/expressionwarning.go | 48 + .../v1beta1/matchresources.go | 90 + .../v1beta1/namedrulewithoperations.go | 95 + .../v1beta1/paramkind.go | 48 + .../admissionregistration/v1beta1/paramref.go | 71 + .../v1beta1/typechecking.go | 44 + .../v1beta1/validatingadmissionpolicy.go | 256 + .../validatingadmissionpolicybinding.go | 247 + .../validatingadmissionpolicybindingspec.go | 72 + .../v1beta1/validatingadmissionpolicyspec.go | 117 + .../validatingadmissionpolicystatus.go | 66 + .../v1beta1/validation.go | 70 + .../admissionregistration/v1beta1/variable.go | 48 + .../v1alpha1/serverstorageversion.go | 11 + .../applyconfigurations/batch/v1/jobspec.go | 27 + .../applyconfigurations/batch/v1/jobstatus.go | 18 + .../applyconfigurations/core/v1/container.go | 9 + .../core/v1/ephemeralcontainer.go | 8 + .../core/v1/ephemeralcontainercommon.go | 9 + .../applyconfigurations/core/v1/hostip.go | 39 + .../core/v1/persistentvolumeclaimstatus.go | 28 +- .../core/v1/persistentvolumestatus.go | 16 +- .../core/v1/podresourceclaimstatus.go | 48 + .../applyconfigurations/core/v1/podstatus.go | 56 +- .../extensions/v1beta1/networkpolicy.go | 11 +- .../extensions/v1beta1/networkpolicystatus.go | 48 - .../exemptprioritylevelconfiguration.go | 48 + .../prioritylevelconfigurationspec.go | 9 + .../exemptprioritylevelconfiguration.go | 48 + .../v1beta1/prioritylevelconfigurationspec.go | 9 + .../exemptprioritylevelconfiguration.go | 48 + .../v1beta2/prioritylevelconfigurationspec.go | 9 + .../exemptprioritylevelconfiguration.go | 48 + .../v1beta3/prioritylevelconfigurationspec.go | 9 + .../applyconfigurations/internal/internal.go | 440 +- .../networking/v1/networkpolicy.go | 11 +- .../networking/v1/networkpolicystatus.go | 48 - .../discovery/aggregated_discovery.go | 6 +- .../discovery/cached/disk/cached_discovery.go | 2 +- .../discovery/cached/memory/memcache.go | 2 +- .../client-go/discovery/discovery_client.go | 48 +- .../v1beta1/admissionregistration_client.go | 10 + .../v1beta1/generated_expansion.go | 4 + .../v1beta1/validatingadmissionpolicy.go | 243 + .../validatingadmissionpolicybinding.go | 197 + .../v1/authentication_client.go | 5 + .../authentication/v1/generated_expansion.go | 2 + .../authentication/v1/selfsubjectreview.go | 64 + .../typed/extensions/v1beta1/networkpolicy.go | 48 - .../typed/networking/v1/networkpolicy.go | 48 - .../k8s.io/client-go/openapi/typeconverter.go | 48 + .../plugin/pkg/client/auth/exec/exec.go | 6 +- vendor/k8s.io/client-go/rest/config.go | 10 +- vendor/k8s.io/client-go/rest/request.go | 28 +- vendor/k8s.io/client-go/rest/url_utils.go | 4 +- vendor/k8s.io/client-go/tools/cache/OWNERS | 4 +- .../client-go/tools/cache/controller.go | 4 - .../client-go/tools/cache/object-names.go | 65 + .../k8s.io/client-go/tools/cache/reflector.go | 30 +- .../client-go/tools/cache/shared_informer.go | 37 +- vendor/k8s.io/client-go/tools/cache/store.go | 31 +- .../client-go/tools/clientcmd/api/types.go | 14 +- .../client-go/tools/clientcmd/loader.go | 24 +- .../tools/leaderelection/leaderelection.go | 5 + .../resourcelock/configmaplock.go | 126 - .../resourcelock/endpointslock.go | 121 - .../leaderelection/resourcelock/interface.go | 42 +- .../k8s.io/client-go/tools/metrics/metrics.go | 48 + vendor/k8s.io/client-go/tools/pager/pager.go | 36 +- vendor/k8s.io/client-go/tools/record/event.go | 5 +- .../client-go/tools/watch/retrywatcher.go | 7 +- vendor/k8s.io/client-go/transport/cache.go | 6 + vendor/k8s.io/client-go/util/cert/cert.go | 34 +- .../kube-openapi/pkg/builder3/util/util.go | 51 - .../k8s.io/kube-openapi/pkg/cached/cache.go | 330 +- .../k8s.io/kube-openapi/pkg/common/common.go | 38 - .../kube-openapi/pkg/handler3/handler.go | 79 +- .../k8s.io/kube-openapi/pkg/internal/flags.go | 1 + .../kube-openapi/pkg/openapiconv/convert.go | 322 - .../kube-openapi/pkg/schemamutation/walker.go | 519 - .../k8s.io/kube-openapi/pkg/spec3/encoding.go | 21 + .../k8s.io/kube-openapi/pkg/spec3/example.go | 14 + .../pkg/spec3/external_documentation.go | 13 + vendor/k8s.io/kube-openapi/pkg/spec3/fuzz.go | 27 + .../k8s.io/kube-openapi/pkg/spec3/header.go | 31 + .../kube-openapi/pkg/spec3/media_type.go | 20 + .../kube-openapi/pkg/spec3/operation.go | 27 + .../kube-openapi/pkg/spec3/parameter.go | 31 + vendor/k8s.io/kube-openapi/pkg/spec3/path.go | 47 +- .../kube-openapi/pkg/spec3/request_body.go | 21 + .../k8s.io/kube-openapi/pkg/spec3/response.go | 52 + .../kube-openapi/pkg/spec3/security_scheme.go | 17 + .../k8s.io/kube-openapi/pkg/spec3/server.go | 26 + vendor/k8s.io/kube-openapi/pkg/spec3/spec.go | 25 + .../kube-openapi/pkg/util/proto/document.go | 2 +- .../pkg/util/proto/document_v3.go | 2 +- .../kube-openapi/pkg/validation/spec/fuzz.go | 502 - .../pkg/validation/spec/gnostic.go | 2 +- vendor/k8s.io/utils/pointer/pointer.go | 283 +- vendor/k8s.io/utils/ptr/OWNERS | 10 + vendor/k8s.io/utils/ptr/README.md | 3 + vendor/k8s.io/utils/ptr/ptr.go | 73 + vendor/modules.txt | 558 +- .../release-utils/version/version.go | 68 +- .../v4/merge/conflict.go | 2 +- .../structured-merge-diff/v4/merge/update.go | 51 +- .../v4/schema/elements.go | 3 +- .../v4/schema/schemaschema.go | 2 +- .../structured-merge-diff/v4/typed/merge.go | 11 +- .../structured-merge-diff/v4/typed/typed.go | 7 +- .../v4/typed/validate.go | 6 + .../v4/value/mapreflect.go | 2 +- .../v4/value/mapunstructured.go | 8 +- .../v4/value/reflectcache.go | 4 +- vendor/sigs.k8s.io/yaml/LICENSE | 256 + vendor/sigs.k8s.io/yaml/OWNERS | 8 +- vendor/sigs.k8s.io/yaml/fields.go | 55 +- vendor/sigs.k8s.io/yaml/goyaml.v2/LICENSE | 201 + .../yaml/goyaml.v2/LICENSE.libyaml | 31 + vendor/sigs.k8s.io/yaml/goyaml.v2/NOTICE | 13 + vendor/sigs.k8s.io/yaml/goyaml.v2/OWNERS | 24 + vendor/sigs.k8s.io/yaml/goyaml.v2/README.md | 143 + vendor/sigs.k8s.io/yaml/goyaml.v2/apic.go | 744 ++ vendor/sigs.k8s.io/yaml/goyaml.v2/decode.go | 815 ++ vendor/sigs.k8s.io/yaml/goyaml.v2/emitterc.go | 1685 ++++ vendor/sigs.k8s.io/yaml/goyaml.v2/encode.go | 390 + vendor/sigs.k8s.io/yaml/goyaml.v2/parserc.go | 1095 ++ vendor/sigs.k8s.io/yaml/goyaml.v2/readerc.go | 412 + vendor/sigs.k8s.io/yaml/goyaml.v2/resolve.go | 258 + vendor/sigs.k8s.io/yaml/goyaml.v2/scannerc.go | 2711 +++++ vendor/sigs.k8s.io/yaml/goyaml.v2/sorter.go | 113 + vendor/sigs.k8s.io/yaml/goyaml.v2/writerc.go | 26 + vendor/sigs.k8s.io/yaml/goyaml.v2/yaml.go | 478 + vendor/sigs.k8s.io/yaml/goyaml.v2/yamlh.go | 739 ++ .../yaml/goyaml.v2/yamlprivateh.go | 173 + vendor/sigs.k8s.io/yaml/yaml.go | 145 +- vendor/sigs.k8s.io/yaml/yaml_go110.go | 17 + 2501 files changed, 284567 insertions(+), 43461 deletions(-) create mode 100644 vendor/github.com/Azure/go-ansiterm/SECURITY.md create mode 100644 vendor/github.com/DataDog/appsec-internal-go/LICENSE create mode 100644 vendor/github.com/DataDog/appsec-internal-go/httpsec/client_ip.go create mode 100644 vendor/github.com/DataDog/appsec-internal-go/netip/ip_default.go create mode 100644 vendor/github.com/DataDog/appsec-internal-go/netip/ip_go119.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/LICENSE create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/cache.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/credit_cards.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/http.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json_scanner.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/memcached.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/obfuscate.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis_tokenizer.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql_tokenizer.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/LICENSE create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/README.md create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/agent_config.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_agent_task.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_asm.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/path.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/products.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/repository.go create mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/tuf.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/LICENSE.txt create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/README.md create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/aggregator.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/buffer.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/buffer_pool.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/buffered_metric_context.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/container.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/event.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/fnv1a.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/format.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/metrics.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/noop.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/options.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/pipe.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/pipe_windows.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/sender.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/service_check.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/statsd.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/telemetry.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/udp.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/uds.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/uds_windows.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/utils.go create mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/worker.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/.gitattributes create mode 100644 vendor/github.com/DataDog/go-libddwaf/.gitignore create mode 100644 vendor/github.com/DataDog/go-libddwaf/LICENSE create mode 100644 vendor/github.com/DataDog/go-libddwaf/README.md create mode 100644 vendor/github.com/DataDog/go-libddwaf/cgo_ref_pool.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/context.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/ctypes.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/decoder.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/embed_darwin_amd64.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/embed_darwin_arm64.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/embed_linux_amd64.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/embed_linux_arm64.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/encoder.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/handle.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/internal/noopfree/noopfree.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/internal/noopfree/noopfree.s create mode 100644 vendor/github.com/DataDog/go-libddwaf/lib/darwin-amd64/_libddwaf.dylib create mode 100644 vendor/github.com/DataDog/go-libddwaf/lib/darwin-arm64/_libddwaf.dylib create mode 100644 vendor/github.com/DataDog/go-libddwaf/lib/linux-amd64/libddwaf.so create mode 100644 vendor/github.com/DataDog/go-libddwaf/lib/linux-arm64/libddwaf.so create mode 100644 vendor/github.com/DataDog/go-libddwaf/lib_dl.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/safe.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/symbols_linux_cgo.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/symbols_linux_purego.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/waf.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/waf_dl.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/waf_dl_unsupported.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/waf_unsupported_go.go create mode 100644 vendor/github.com/DataDog/go-libddwaf/waf_unsupported_target.go create mode 100644 vendor/github.com/DataDog/go-tuf/LICENSE create mode 100644 vendor/github.com/DataDog/go-tuf/client/client.go create mode 100644 vendor/github.com/DataDog/go-tuf/client/delegations.go create mode 100644 vendor/github.com/DataDog/go-tuf/client/errors.go create mode 100644 vendor/github.com/DataDog/go-tuf/client/file_store.go create mode 100644 vendor/github.com/DataDog/go-tuf/client/local_store.go create mode 100644 vendor/github.com/DataDog/go-tuf/client/remote_store.go create mode 100644 vendor/github.com/DataDog/go-tuf/data/hex_bytes.go create mode 100644 vendor/github.com/DataDog/go-tuf/data/types.go create mode 100644 vendor/github.com/DataDog/go-tuf/internal/roles/roles.go create mode 100644 vendor/github.com/DataDog/go-tuf/internal/sets/strings.go create mode 100644 vendor/github.com/DataDog/go-tuf/pkg/keys/deprecated_ecdsa.go create mode 100644 vendor/github.com/DataDog/go-tuf/pkg/keys/ecdsa.go create mode 100644 vendor/github.com/DataDog/go-tuf/pkg/keys/ed25519.go create mode 100644 vendor/github.com/DataDog/go-tuf/pkg/keys/keys.go create mode 100644 vendor/github.com/DataDog/go-tuf/pkg/keys/pkix.go create mode 100644 vendor/github.com/DataDog/go-tuf/pkg/keys/rsa.go create mode 100644 vendor/github.com/DataDog/go-tuf/pkg/targets/delegation.go create mode 100644 vendor/github.com/DataDog/go-tuf/pkg/targets/hash_bins.go create mode 100644 vendor/github.com/DataDog/go-tuf/util/util.go create mode 100644 vendor/github.com/DataDog/go-tuf/verify/db.go create mode 100644 vendor/github.com/DataDog/go-tuf/verify/errors.go create mode 100644 vendor/github.com/DataDog/go-tuf/verify/verify.go create mode 100644 vendor/github.com/DataDog/sketches-go/LICENSE create mode 100644 vendor/github.com/DataDog/sketches-go/LICENSE-3rdparty.csv create mode 100644 vendor/github.com/DataDog/sketches-go/NOTICE create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/ddsketch.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/encoding/encoding.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/encoding/flag.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/mapping/bit_operation_helper.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/mapping/cubically_interpolated_mapping.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/mapping/index_mapping.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/mapping/linearly_interpolated_mapping.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/mapping/logarithmic_mapping.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/pb/sketchpb/ddsketch.pb.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/stat/summary.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/store/bin.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/store/buffered_paginated.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/store/collapsing_highest_dense_store.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/store/collapsing_lowest_dense_store.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/store/dense_store.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/store/sparse.go create mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/store/store.go create mode 100644 vendor/github.com/alibabacloud-go/tea-xml/LICENSE create mode 100644 vendor/github.com/aliyun/credentials-go/credentials/credential_model.go create mode 100644 vendor/github.com/aliyun/credentials-go/credentials/oidc_credential_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/ci-find-smithy-go.sh create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/auth/scheme.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/arn.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/generate.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/host.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partition.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/ini/number_helper.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/arn/arn_member.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/s3100continue.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/s3/bucketer.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/s3/handwritten_paginators.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/s3/serialize_immutable_hostname_bucket.go create mode 100644 vendor/github.com/aws/smithy-go/endpoints/endpoint.go create mode 100644 vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/doc.go create mode 100644 vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/strings.go create mode 100644 vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go create mode 100644 vendor/github.com/aws/smithy-go/properties.go create mode 100644 vendor/github.com/aws/smithy-go/transport/http/middleware_header_comment.go create mode 100644 vendor/github.com/buildkite/agent/v3/env/environment.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/ordered/map.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/ordered/slice.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/ordered/strings.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/ordered/tuple.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/ordered/unmarshal.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/ordered/yaml.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/doc.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/interpolate.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/interpolate_matrix.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/json.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/parser.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/pipeline.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/pipeline_invariants.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/plugin.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/plugins.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/sign.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/step.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/step_command.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/step_command_matrix.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/step_group.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/step_input.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/step_scalar.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/step_trigger.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/step_unknown.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/step_wait.go create mode 100644 vendor/github.com/buildkite/agent/v3/internal/pipeline/steps.go create mode 100644 vendor/github.com/buildkite/agent/v3/tracetools/doc.go create mode 100644 vendor/github.com/buildkite/agent/v3/tracetools/propagate.go create mode 100644 vendor/github.com/buildkite/agent/v3/tracetools/span.go create mode 100644 vendor/github.com/buildkite/agent/v3/version/VERSION create mode 100644 vendor/github.com/buildkite/agent/v3/version/version.go create mode 100644 vendor/github.com/buildkite/interpolate/LICENSE.txt create mode 100644 vendor/github.com/buildkite/interpolate/README.md create mode 100644 vendor/github.com/buildkite/interpolate/env.go create mode 100644 vendor/github.com/buildkite/interpolate/interpolate.go create mode 100644 vendor/github.com/buildkite/interpolate/parser.go create mode 100644 vendor/github.com/cloudflare/circl/math/primes.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go create mode 100644 vendor/github.com/distribution/reference/.gitattributes create mode 100644 vendor/github.com/distribution/reference/.gitignore create mode 100644 vendor/github.com/distribution/reference/.golangci.yml create mode 100644 vendor/github.com/distribution/reference/CODE-OF-CONDUCT.md create mode 100644 vendor/github.com/distribution/reference/CONTRIBUTING.md create mode 100644 vendor/github.com/distribution/reference/GOVERNANCE.md create mode 100644 vendor/github.com/distribution/reference/LICENSE create mode 100644 vendor/github.com/distribution/reference/MAINTAINERS create mode 100644 vendor/github.com/distribution/reference/Makefile create mode 100644 vendor/github.com/distribution/reference/README.md create mode 100644 vendor/github.com/distribution/reference/SECURITY.md create mode 100644 vendor/github.com/distribution/reference/distribution-logo.svg rename vendor/github.com/{docker => }/distribution/reference/helpers.go (94%) rename vendor/github.com/{docker => }/distribution/reference/normalize.go (52%) rename vendor/github.com/{docker => }/distribution/reference/reference.go (93%) create mode 100644 vendor/github.com/distribution/reference/regexp.go create mode 100644 vendor/github.com/distribution/reference/sort.go delete mode 100644 vendor/github.com/docker/cli/cli/command/streams.go delete mode 100644 vendor/github.com/docker/cli/cli/flags/options_deprecated.go create mode 100644 vendor/github.com/docker/cli/cli/hints/hints.go create mode 100644 vendor/github.com/docker/distribution/reference/helpers_deprecated.go create mode 100644 vendor/github.com/docker/distribution/reference/normalize_deprecated.go create mode 100644 vendor/github.com/docker/distribution/reference/reference_deprecated.go delete mode 100644 vendor/github.com/docker/distribution/reference/regexp.go create mode 100644 vendor/github.com/docker/distribution/reference/regexp_deprecated.go create mode 100644 vendor/github.com/docker/distribution/reference/sort_deprecated.go create mode 100644 vendor/github.com/docker/docker/api/types/container/change_response_deprecated.go create mode 100644 vendor/github.com/docker/docker/api/types/container/change_type.go create mode 100644 vendor/github.com/docker/docker/api/types/container/change_types.go delete mode 100644 vendor/github.com/docker/docker/api/types/container/container_changes.go delete mode 100644 vendor/github.com/docker/docker/api/types/container/deprecated.go create mode 100644 vendor/github.com/docker/docker/api/types/container/filesystem_change.go rename vendor/github.com/docker/docker/api/types/container/{host_config.go => hostconfig.go} (84%) delete mode 100644 vendor/github.com/docker/docker/api/types/deprecated.go create mode 100644 vendor/github.com/docker/docker/api/types/filters/errors.go create mode 100644 vendor/github.com/docker/docker/api/types/image/opts.go create mode 100644 vendor/github.com/docker/docker/api/types/registry/authconfig.go delete mode 100644 vendor/github.com/docker/docker/api/types/volume/deprecated.go delete mode 100644 vendor/github.com/docker/docker/pkg/ioutils/temp_unix.go delete mode 100644 vendor/github.com/docker/docker/pkg/ioutils/temp_windows.go create mode 100644 vendor/github.com/docker/docker/pkg/ioutils/tempdir_deprecated.go create mode 100644 vendor/github.com/docker/docker/registry/search.go create mode 100644 vendor/github.com/dustin/go-humanize/.travis.yml create mode 100644 vendor/github.com/dustin/go-humanize/LICENSE create mode 100644 vendor/github.com/dustin/go-humanize/README.markdown create mode 100644 vendor/github.com/dustin/go-humanize/big.go create mode 100644 vendor/github.com/dustin/go-humanize/bigbytes.go create mode 100644 vendor/github.com/dustin/go-humanize/bytes.go create mode 100644 vendor/github.com/dustin/go-humanize/comma.go create mode 100644 vendor/github.com/dustin/go-humanize/commaf.go create mode 100644 vendor/github.com/dustin/go-humanize/ftoa.go create mode 100644 vendor/github.com/dustin/go-humanize/humanize.go create mode 100644 vendor/github.com/dustin/go-humanize/number.go create mode 100644 vendor/github.com/dustin/go-humanize/ordinals.go create mode 100644 vendor/github.com/dustin/go-humanize/si.go create mode 100644 vendor/github.com/dustin/go-humanize/times.go create mode 100644 vendor/github.com/ebitengine/purego/.gitignore rename vendor/github.com/{matttproud/golang_protobuf_extensions => ebitengine/purego}/LICENSE (100%) create mode 100644 vendor/github.com/ebitengine/purego/README.md create mode 100644 vendor/github.com/ebitengine/purego/abi_amd64.h create mode 100644 vendor/github.com/ebitengine/purego/abi_arm64.h create mode 100644 vendor/github.com/ebitengine/purego/cgo.go create mode 100644 vendor/github.com/ebitengine/purego/dlerror.go create mode 100644 vendor/github.com/ebitengine/purego/dlfcn.go create mode 100644 vendor/github.com/ebitengine/purego/dlfcn_darwin.go create mode 100644 vendor/github.com/ebitengine/purego/dlfcn_freebsd.go create mode 100644 vendor/github.com/ebitengine/purego/dlfcn_linux.go create mode 100644 vendor/github.com/ebitengine/purego/dlfcn_nocgo_linux.go create mode 100644 vendor/github.com/ebitengine/purego/dlfcn_stubs.s create mode 100644 vendor/github.com/ebitengine/purego/func.go create mode 100644 vendor/github.com/ebitengine/purego/go_runtime.go create mode 100644 vendor/github.com/ebitengine/purego/internal/cgo/syscall_cgo_unix.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/abi_amd64.h create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/abi_arm64.h create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/asm_amd64.s create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/asm_arm64.s create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/callbacks.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/doc.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/freebsd.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/go_darwin_amd64.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/go_darwin_arm64.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/go_freebsd_amd64.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/go_freebsd_arm64.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/go_libinit.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_amd64.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_arm64.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/go_setenv.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/go_util.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/iscgo.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_darwin.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_freebsd.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_linux.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/setenv.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/symbols.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_darwin.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_freebsd.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_linux.go create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_amd64.s create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_arm64.s create mode 100644 vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_stubs.s create mode 100644 vendor/github.com/ebitengine/purego/internal/strings/strings.go create mode 100644 vendor/github.com/ebitengine/purego/is_ios.go create mode 100644 vendor/github.com/ebitengine/purego/nocgo.go create mode 100644 vendor/github.com/ebitengine/purego/sys_amd64.s create mode 100644 vendor/github.com/ebitengine/purego/sys_arm64.s create mode 100644 vendor/github.com/ebitengine/purego/sys_unix_arm64.s create mode 100644 vendor/github.com/ebitengine/purego/syscall.go create mode 100644 vendor/github.com/ebitengine/purego/syscall_cgo_linux.go create mode 100644 vendor/github.com/ebitengine/purego/syscall_sysv.go create mode 100644 vendor/github.com/ebitengine/purego/syscall_windows.go create mode 100644 vendor/github.com/ebitengine/purego/zcallback_amd64.s create mode 100644 vendor/github.com/ebitengine/purego/zcallback_arm64.s create mode 100644 vendor/github.com/fatih/color/color_windows.go create mode 100644 vendor/github.com/fsnotify/fsnotify/.cirrus.yml create mode 100644 vendor/github.com/go-logr/logr/SECURITY.md create mode 100644 vendor/github.com/go-playground/validator/v10/options.go create mode 100644 vendor/github.com/goccy/go-json/.codecov.yml create mode 100644 vendor/github.com/goccy/go-json/.gitignore create mode 100644 vendor/github.com/goccy/go-json/.golangci.yml create mode 100644 vendor/github.com/goccy/go-json/CHANGELOG.md create mode 100644 vendor/github.com/goccy/go-json/LICENSE create mode 100644 vendor/github.com/goccy/go-json/Makefile create mode 100644 vendor/github.com/goccy/go-json/README.md create mode 100644 vendor/github.com/goccy/go-json/color.go create mode 100644 vendor/github.com/goccy/go-json/decode.go create mode 100644 vendor/github.com/goccy/go-json/docker-compose.yml create mode 100644 vendor/github.com/goccy/go-json/encode.go create mode 100644 vendor/github.com/goccy/go-json/error.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/array.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/assign.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/bool.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/bytes.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/compile.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/compile_race.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/context.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/float.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/func.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/int.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/interface.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/invalid.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/map.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/number.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/option.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/path.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/ptr.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/slice.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/stream.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/string.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/struct.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/type.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/uint.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/code.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compact.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compiler.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/context.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/decode_rune.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/encoder.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/indent.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/int.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/map112.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/map113.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/opcode.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/option.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/optype.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/query.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/string.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/string_table.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/errors/error.go create mode 100644 vendor/github.com/goccy/go-json/internal/runtime/rtype.go create mode 100644 vendor/github.com/goccy/go-json/internal/runtime/struct_field.go create mode 100644 vendor/github.com/goccy/go-json/internal/runtime/type.go create mode 100644 vendor/github.com/goccy/go-json/json.go create mode 100644 vendor/github.com/goccy/go-json/option.go create mode 100644 vendor/github.com/goccy/go-json/path.go create mode 100644 vendor/github.com/goccy/go-json/query.go create mode 100644 vendor/github.com/google/certificate-transparency-go/x509/root_wasip1.go create mode 100644 vendor/github.com/google/certificate-transparency-go/x509/root_zos.go create mode 100644 vendor/github.com/google/gnostic-models/LICENSE create mode 100644 vendor/github.com/google/gnostic-models/compiler/README.md create mode 100644 vendor/github.com/google/gnostic-models/compiler/context.go create mode 100644 vendor/github.com/google/gnostic-models/compiler/error.go create mode 100644 vendor/github.com/google/gnostic-models/compiler/extensions.go create mode 100644 vendor/github.com/google/gnostic-models/compiler/helpers.go create mode 100644 vendor/github.com/google/gnostic-models/compiler/main.go create mode 100644 vendor/github.com/google/gnostic-models/compiler/reader.go create mode 100644 vendor/github.com/google/gnostic-models/extensions/README.md create mode 100644 vendor/github.com/google/gnostic-models/extensions/extension.pb.go create mode 100644 vendor/github.com/google/gnostic-models/extensions/extension.proto create mode 100644 vendor/github.com/google/gnostic-models/extensions/extensions.go create mode 100644 vendor/github.com/google/gnostic-models/jsonschema/README.md create mode 100644 vendor/github.com/google/gnostic-models/jsonschema/base.go create mode 100644 vendor/github.com/google/gnostic-models/jsonschema/display.go create mode 100644 vendor/github.com/google/gnostic-models/jsonschema/models.go create mode 100644 vendor/github.com/google/gnostic-models/jsonschema/operations.go create mode 100644 vendor/github.com/google/gnostic-models/jsonschema/reader.go create mode 100644 vendor/github.com/google/gnostic-models/jsonschema/schema.json create mode 100644 vendor/github.com/google/gnostic-models/jsonschema/writer.go create mode 100644 vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.go create mode 100644 vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.pb.go create mode 100644 vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.proto create mode 100644 vendor/github.com/google/gnostic-models/openapiv2/README.md create mode 100644 vendor/github.com/google/gnostic-models/openapiv2/document.go create mode 100644 vendor/github.com/google/gnostic-models/openapiv2/openapi-2.0.json rename vendor/github.com/google/{gnostic => gnostic-models}/openapiv3/OpenAPIv3.go (99%) rename vendor/github.com/google/{gnostic => gnostic-models}/openapiv3/OpenAPIv3.pb.go (99%) rename vendor/github.com/google/{gnostic => gnostic-models}/openapiv3/OpenAPIv3.proto (99%) rename vendor/github.com/google/{gnostic => gnostic-models}/openapiv3/README.md (89%) rename vendor/github.com/google/{gnostic => gnostic-models}/openapiv3/annotations.pb.go (90%) rename vendor/github.com/google/{gnostic => gnostic-models}/openapiv3/annotations.proto (96%) rename vendor/github.com/google/{gnostic => gnostic-models}/openapiv3/document.go (96%) delete mode 100644 vendor/github.com/google/gnostic/openapiv3/openapi-3.0.json delete mode 100644 vendor/github.com/google/gnostic/openapiv3/openapi-3.1.json rename vendor/github.com/google/go-cmp/cmp/{export_unsafe.go => export.go} (94%) delete mode 100644 vendor/github.com/google/go-cmp/cmp/export_panic.go rename vendor/github.com/google/go-cmp/cmp/internal/value/{pointer_unsafe.go => pointer.go} (95%) delete mode 100644 vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go delete mode 100644 vendor/github.com/google/go-github/v50/github/event.go delete mode 100644 vendor/github.com/google/go-github/v50/github/orgs_audit_log.go rename vendor/github.com/google/go-github/{v50 => v55}/AUTHORS (89%) rename vendor/github.com/google/go-github/{v50 => v55}/LICENSE (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/actions.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/actions_artifacts.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/actions_cache.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/actions_oidc.go (100%) create mode 100644 vendor/github.com/google/go-github/v55/github/actions_required_workflows.go rename vendor/github.com/google/go-github/{v50 => v55}/github/actions_runner_groups.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/actions_runners.go (85%) rename vendor/github.com/google/go-github/{v50 => v55}/github/actions_secrets.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/actions_variables.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/actions_workflow_jobs.go (98%) rename vendor/github.com/google/go-github/{v50 => v55}/github/actions_workflow_runs.go (89%) rename vendor/github.com/google/go-github/{v50 => v55}/github/actions_workflows.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/activity.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/activity_events.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/activity_notifications.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/activity_star.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/activity_watching.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/admin.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/admin_orgs.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/admin_stats.go (99%) rename vendor/github.com/google/go-github/{v50 => v55}/github/admin_users.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/apps.go (93%) rename vendor/github.com/google/go-github/{v50 => v55}/github/apps_hooks.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/apps_hooks_deliveries.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/apps_installation.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/apps_manifest.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/apps_marketplace.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/authorizations.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/billing.go (95%) rename vendor/github.com/google/go-github/{v50 => v55}/github/checks.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/code-scanning.go (57%) create mode 100644 vendor/github.com/google/go-github/v55/github/codespaces.go create mode 100644 vendor/github.com/google/go-github/v55/github/codespaces_secrets.go rename vendor/github.com/google/go-github/{v50 => v55}/github/dependabot.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/dependabot_alerts.go (93%) rename vendor/github.com/google/go-github/{v50 => v55}/github/dependabot_secrets.go (94%) create mode 100644 vendor/github.com/google/go-github/v55/github/dependency_graph.go rename vendor/github.com/google/go-github/{v50 => v55}/github/doc.go (87%) rename vendor/github.com/google/go-github/{v50 => v55}/github/enterprise.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/enterprise_actions_runners.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/enterprise_audit_log.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/enterprise_code_security_and_analysis.go (100%) create mode 100644 vendor/github.com/google/go-github/v55/github/event.go rename vendor/github.com/google/go-github/{v50 => v55}/github/event_types.go (83%) rename vendor/github.com/google/go-github/{v50 => v55}/github/gists.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/gists_comments.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/git.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/git_blobs.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/git_commits.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/git_refs.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/git_tags.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/git_trees.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/github-accessors.go (88%) rename vendor/github.com/google/go-github/{v50 => v55}/github/github.go (88%) rename vendor/github.com/google/go-github/{v50 => v55}/github/gitignore.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/interactions.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/interactions_orgs.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/interactions_repos.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/issue_import.go (97%) rename vendor/github.com/google/go-github/{v50 => v55}/github/issues.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/issues_assignees.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/issues_comments.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/issues_events.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/issues_labels.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/issues_milestones.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/issues_timeline.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/licenses.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/messages.go (59%) rename vendor/github.com/google/go-github/{v50 => v55}/github/migrations.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/migrations_source_import.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/migrations_user.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/misc.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/orgs.go (95%) rename vendor/github.com/google/go-github/{v50 => v55}/github/orgs_actions_allowed.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/orgs_actions_permissions.go (100%) create mode 100644 vendor/github.com/google/go-github/v55/github/orgs_audit_log.go create mode 100644 vendor/github.com/google/go-github/v55/github/orgs_credential_authorizations.go rename vendor/github.com/google/go-github/{v50 => v55}/github/orgs_custom_roles.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/orgs_hooks.go (100%) create mode 100644 vendor/github.com/google/go-github/v55/github/orgs_hooks_configuration.go rename vendor/github.com/google/go-github/{v50 => v55}/github/orgs_hooks_deliveries.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/orgs_members.go (99%) rename vendor/github.com/google/go-github/{v50 => v55}/github/orgs_outside_collaborators.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/orgs_packages.go (100%) create mode 100644 vendor/github.com/google/go-github/v55/github/orgs_personal_access_tokens.go rename vendor/github.com/google/go-github/{v50 => v55}/github/orgs_projects.go (100%) create mode 100644 vendor/github.com/google/go-github/v55/github/orgs_rules.go rename vendor/github.com/google/go-github/{v50 => v55}/github/orgs_security_managers.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/orgs_users_blocking.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/packages.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/projects.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/pulls.go (99%) rename vendor/github.com/google/go-github/{v50 => v55}/github/pulls_comments.go (97%) rename vendor/github.com/google/go-github/{v50 => v55}/github/pulls_reviewers.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/pulls_reviews.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/pulls_threads.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/reactions.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos.go (96%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_actions_access.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_actions_allowed.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_actions_permissions.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_autolinks.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_codeowners.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_collaborators.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_comments.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_commits.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_community_health.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_contents.go (94%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_deployment_branch_policies.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_deployments.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_environments.go (96%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_forks.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_hooks.go (100%) create mode 100644 vendor/github.com/google/go-github/v55/github/repos_hooks_configuration.go rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_hooks_deliveries.go (97%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_invitations.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_keys.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_lfs.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_merging.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_pages.go (68%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_prereceive_hooks.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_projects.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_releases.go (100%) create mode 100644 vendor/github.com/google/go-github/v55/github/repos_rules.go rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_stats.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_statuses.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_tags.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/repos_traffic.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/scim.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/search.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/secret_scanning.go (91%) create mode 100644 vendor/github.com/google/go-github/v55/github/security_advisories.go rename vendor/github.com/google/go-github/{v50 => v55}/github/strings.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/teams.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/teams_discussion_comments.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/teams_discussions.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/teams_members.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/timestamp.go (90%) rename vendor/github.com/google/go-github/{v50 => v55}/github/users.go (98%) rename vendor/github.com/google/go-github/{v50 => v55}/github/users_administration.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/users_blocking.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/users_emails.go (73%) rename vendor/github.com/google/go-github/{v50 => v55}/github/users_followers.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/users_gpg_keys.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/users_keys.go (96%) rename vendor/github.com/google/go-github/{v50 => v55}/github/users_packages.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/users_projects.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/users_ssh_signing_keys.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/with_appengine.go (100%) rename vendor/github.com/google/go-github/{v50 => v55}/github/without_appengine.go (100%) create mode 100644 vendor/github.com/google/s2a-go/retry/retry.go create mode 100644 vendor/github.com/google/s2a-go/testdata/mds_client_cert.pem create mode 100644 vendor/github.com/google/s2a-go/testdata/mds_client_key.pem create mode 100644 vendor/github.com/google/s2a-go/testdata/mds_root_cert.pem create mode 100644 vendor/github.com/google/s2a-go/testdata/mds_server_cert.pem create mode 100644 vendor/github.com/google/s2a-go/testdata/mds_server_key.pem create mode 100644 vendor/github.com/google/s2a-go/testdata/self_signed_cert.pem create mode 100644 vendor/github.com/google/s2a-go/testdata/self_signed_key.pem delete mode 100644 vendor/github.com/google/uuid/.travis.yml create mode 100644 vendor/github.com/google/uuid/CHANGELOG.md create mode 100644 vendor/github.com/gowebpki/jcs/.gitignore create mode 100644 vendor/github.com/gowebpki/jcs/LICENSE create mode 100644 vendor/github.com/gowebpki/jcs/README.md create mode 100644 vendor/github.com/gowebpki/jcs/es6numfmt.go create mode 100644 vendor/github.com/gowebpki/jcs/jcs.go create mode 100644 vendor/github.com/hashicorp/go-retryablehttp/CHANGELOG.md create mode 100644 vendor/github.com/hashicorp/go-retryablehttp/CODEOWNERS create mode 100644 vendor/github.com/klauspost/compress/SECURITY.md create mode 100644 vendor/github.com/klauspost/compress/flate/matchlen_amd64.go create mode 100644 vendor/github.com/klauspost/compress/flate/matchlen_amd64.s create mode 100644 vendor/github.com/klauspost/compress/flate/matchlen_generic.go create mode 100644 vendor/github.com/klauspost/compress/zstd/matchlen_amd64.go create mode 100644 vendor/github.com/klauspost/compress/zstd/matchlen_amd64.s create mode 100644 vendor/github.com/klauspost/compress/zstd/matchlen_generic.go create mode 100644 vendor/github.com/lestrrat-go/blackmagic/.gitignore create mode 100644 vendor/github.com/lestrrat-go/blackmagic/LICENSE create mode 100644 vendor/github.com/lestrrat-go/blackmagic/README.md create mode 100644 vendor/github.com/lestrrat-go/blackmagic/blackmagic.go create mode 100644 vendor/github.com/lestrrat-go/httpcc/.gitignore create mode 100644 vendor/github.com/lestrrat-go/httpcc/LICENSE create mode 100644 vendor/github.com/lestrrat-go/httpcc/README.md create mode 100644 vendor/github.com/lestrrat-go/httpcc/directives.go create mode 100644 vendor/github.com/lestrrat-go/httpcc/httpcc.go create mode 100644 vendor/github.com/lestrrat-go/httprc/.gitignore create mode 100644 vendor/github.com/lestrrat-go/httprc/.golangci.yml create mode 100644 vendor/github.com/lestrrat-go/httprc/Changes create mode 100644 vendor/github.com/lestrrat-go/httprc/LICENSE create mode 100644 vendor/github.com/lestrrat-go/httprc/README.md create mode 100644 vendor/github.com/lestrrat-go/httprc/cache.go create mode 100644 vendor/github.com/lestrrat-go/httprc/fetcher.go create mode 100644 vendor/github.com/lestrrat-go/httprc/httprc.go create mode 100644 vendor/github.com/lestrrat-go/httprc/options.yaml create mode 100644 vendor/github.com/lestrrat-go/httprc/options_gen.go create mode 100644 vendor/github.com/lestrrat-go/httprc/queue.go create mode 100644 vendor/github.com/lestrrat-go/httprc/whitelist.go create mode 100644 vendor/github.com/lestrrat-go/iter/LICENSE create mode 100644 vendor/github.com/lestrrat-go/iter/arrayiter/arrayiter.go create mode 100644 vendor/github.com/lestrrat-go/iter/mapiter/mapiter.go rename vendor/github.com/{spf13/jwalterweatherman => lestrrat-go/jwx/v2}/LICENSE (96%) create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/cert/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/cert/cert.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/cert/chain.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/base64/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/base64/asmbase64.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/base64/base64.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/ecutil/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/ecutil/ecutil.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/iter/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/iter/mapiter.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/json/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/json/goccy.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/json/json.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/json/registry.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/json/stdlib.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/keyconv/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/keyconv/keyconv.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/pool/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/internal/pool/pool.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwa/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwa/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwa/compression_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwa/content_encryption_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwa/elliptic_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwa/jwa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwa/key_encryption_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwa/key_type_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwa/secp2561k.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwa/signature_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/cache.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/ecdsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/ecdsa_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/es256k.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/fetch.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/interface_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/io.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/jwk.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/key_ops.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/okp.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/okp_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/options.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/options.yaml create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/options_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/rsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/rsa_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/set.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/symmetric.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/symmetric_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/usage.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jwk/whitelist.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/ecdsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/eddsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/es256k.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/headers.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/headers_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/hmac.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/io.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/jws.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/key_provider.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/message.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/options.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/options.yaml create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/options_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/rsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/signer.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/jws/verifier.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/x25519/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v2/x25519/x25519.go create mode 100644 vendor/github.com/lestrrat-go/option/.gitignore create mode 100644 vendor/github.com/lestrrat-go/option/LICENSE create mode 100644 vendor/github.com/lestrrat-go/option/README.md create mode 100644 vendor/github.com/lestrrat-go/option/option.go delete mode 100644 vendor/github.com/letsencrypt/boulder/core/proto/core.pb.go delete mode 100644 vendor/github.com/letsencrypt/boulder/core/proto/core.proto delete mode 100644 vendor/github.com/letsencrypt/boulder/errors/errors.go delete mode 100644 vendor/github.com/letsencrypt/boulder/features/featureflag_string.go delete mode 100644 vendor/github.com/letsencrypt/boulder/features/features.go delete mode 100644 vendor/github.com/letsencrypt/boulder/sa/proto/sa.pb.go delete mode 100644 vendor/github.com/letsencrypt/boulder/sa/proto/sa.proto delete mode 100644 vendor/github.com/letsencrypt/boulder/sa/proto/sa_grpc.pb.go delete mode 100644 vendor/github.com/letsencrypt/boulder/sa/proto/subsets.go create mode 100644 vendor/github.com/letsencrypt/boulder/strictyaml/yaml.go create mode 100644 vendor/github.com/matttproud/golang_protobuf_extensions/v2/LICENSE rename vendor/github.com/matttproud/golang_protobuf_extensions/{ => v2}/NOTICE (100%) rename vendor/github.com/matttproud/golang_protobuf_extensions/{ => v2}/pbutil/.gitignore (100%) rename vendor/github.com/matttproud/golang_protobuf_extensions/{ => v2}/pbutil/Makefile (100%) rename vendor/github.com/matttproud/golang_protobuf_extensions/{ => v2}/pbutil/decode.go (83%) rename vendor/github.com/matttproud/golang_protobuf_extensions/{ => v2}/pbutil/doc.go (100%) rename vendor/github.com/matttproud/golang_protobuf_extensions/{ => v2}/pbutil/encode.go (91%) rename vendor/github.com/{spf13/jwalterweatherman => oleiade/reflections}/.gitignore (94%) create mode 100644 vendor/github.com/oleiade/reflections/AUTHORS.md create mode 100644 vendor/github.com/oleiade/reflections/LICENSE create mode 100644 vendor/github.com/oleiade/reflections/README.md create mode 100644 vendor/github.com/oleiade/reflections/reflections.go rename vendor/github.com/{docker/distribution => opencontainers/go-digest}/digestset/set.go (91%) create mode 100644 vendor/github.com/outcaste-io/ristretto/.deepsource.toml create mode 100644 vendor/github.com/outcaste-io/ristretto/.mailmap create mode 100644 vendor/github.com/outcaste-io/ristretto/CHANGELOG.md create mode 100644 vendor/github.com/outcaste-io/ristretto/LICENSE create mode 100644 vendor/github.com/outcaste-io/ristretto/README.md create mode 100644 vendor/github.com/outcaste-io/ristretto/cache.go create mode 100644 vendor/github.com/outcaste-io/ristretto/metrics.go create mode 100644 vendor/github.com/outcaste-io/ristretto/policy.go create mode 100644 vendor/github.com/outcaste-io/ristretto/ring.go create mode 100644 vendor/github.com/outcaste-io/ristretto/sketch.go create mode 100644 vendor/github.com/outcaste-io/ristretto/store.go create mode 100644 vendor/github.com/outcaste-io/ristretto/test.sh create mode 100644 vendor/github.com/outcaste-io/ristretto/ttl.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/LICENSE create mode 100644 vendor/github.com/outcaste-io/ristretto/z/README.md create mode 100644 vendor/github.com/outcaste-io/ristretto/z/allocator.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/bbloom.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/btree.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/buffer.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/calloc.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/calloc_32bit.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/calloc_64bit.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/calloc_jemalloc.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/calloc_nojemalloc.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/file.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/file_default.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/file_linux.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/flags.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/histogram.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/mmap.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/mmap_darwin.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/mmap_linux.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/mmap_plan9.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/mmap_unix.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/mmap_wasip1.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/mmap_windows.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/rtutil.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/rtutil.s create mode 100644 vendor/github.com/outcaste-io/ristretto/z/simd/baseline.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/simd/search.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/simd/search_amd64.s create mode 100644 vendor/github.com/outcaste-io/ristretto/z/simd/stub_search_amd64.go create mode 100644 vendor/github.com/outcaste-io/ristretto/z/z.go create mode 100644 vendor/github.com/philhofer/fwd/LICENSE.md create mode 100644 vendor/github.com/philhofer/fwd/README.md create mode 100644 vendor/github.com/philhofer/fwd/reader.go create mode 100644 vendor/github.com/philhofer/fwd/writer.go create mode 100644 vendor/github.com/philhofer/fwd/writer_appengine.go create mode 100644 vendor/github.com/philhofer/fwd/writer_tinygo.go create mode 100644 vendor/github.com/philhofer/fwd/writer_unsafe.go create mode 100644 vendor/github.com/prometheus/procfs/fs_statfs_notype.go create mode 100644 vendor/github.com/prometheus/procfs/fs_statfs_type.go create mode 100644 vendor/github.com/prometheus/procfs/net_route.go create mode 100644 vendor/github.com/prometheus/procfs/net_wireless.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v2/.gitignore create mode 100644 vendor/github.com/puzpuzpuz/xsync/v2/BENCHMARKS.md create mode 100644 vendor/github.com/puzpuzpuz/xsync/v2/LICENSE create mode 100644 vendor/github.com/puzpuzpuz/xsync/v2/README.md create mode 100644 vendor/github.com/puzpuzpuz/xsync/v2/counter.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v2/map.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v2/mapof.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v2/mpmcqueue.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v2/mpmcqueueof.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v2/rbmutex.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v2/util.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v2/util_mapof.go create mode 100644 vendor/github.com/sagikazarmark/locafero/.editorconfig create mode 100644 vendor/github.com/sagikazarmark/locafero/.envrc create mode 100644 vendor/github.com/sagikazarmark/locafero/.gitignore create mode 100644 vendor/github.com/sagikazarmark/locafero/.golangci.yaml create mode 100644 vendor/github.com/sagikazarmark/locafero/LICENSE create mode 100644 vendor/github.com/sagikazarmark/locafero/README.md create mode 100644 vendor/github.com/sagikazarmark/locafero/file_type.go create mode 100644 vendor/github.com/sagikazarmark/locafero/finder.go create mode 100644 vendor/github.com/sagikazarmark/locafero/flake.lock create mode 100644 vendor/github.com/sagikazarmark/locafero/flake.nix create mode 100644 vendor/github.com/sagikazarmark/locafero/helpers.go create mode 100644 vendor/github.com/sagikazarmark/locafero/justfile create mode 100644 vendor/github.com/sagikazarmark/slog-shim/.editorconfig create mode 100644 vendor/github.com/sagikazarmark/slog-shim/.envrc create mode 100644 vendor/github.com/sagikazarmark/slog-shim/.gitignore create mode 100644 vendor/github.com/sagikazarmark/slog-shim/LICENSE create mode 100644 vendor/github.com/sagikazarmark/slog-shim/README.md create mode 100644 vendor/github.com/sagikazarmark/slog-shim/attr.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/attr_120.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/flake.lock create mode 100644 vendor/github.com/sagikazarmark/slog-shim/flake.nix create mode 100644 vendor/github.com/sagikazarmark/slog-shim/handler.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/handler_120.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/json_handler.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/json_handler_120.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/level.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/level_120.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/logger.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/logger_120.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/record.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/record_120.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/text_handler.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/text_handler_120.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/value.go create mode 100644 vendor/github.com/sagikazarmark/slog-shim/value_120.go rename vendor/github.com/{theupdateframework/go-tuf => secure-systems-lab/go-securesystemslib}/encrypted/encrypted.go (64%) create mode 100644 vendor/github.com/segmentio/asm/LICENSE create mode 100644 vendor/github.com/segmentio/asm/base64/base64.go create mode 100644 vendor/github.com/segmentio/asm/base64/base64_amd64.go create mode 100644 vendor/github.com/segmentio/asm/base64/base64_arm64.go create mode 100644 vendor/github.com/segmentio/asm/base64/base64_asm.go create mode 100644 vendor/github.com/segmentio/asm/base64/base64_default.go create mode 100644 vendor/github.com/segmentio/asm/base64/decode_amd64.go create mode 100644 vendor/github.com/segmentio/asm/base64/decode_amd64.s create mode 100644 vendor/github.com/segmentio/asm/base64/decode_arm64.go create mode 100644 vendor/github.com/segmentio/asm/base64/decode_arm64.s create mode 100644 vendor/github.com/segmentio/asm/base64/encode_amd64.go create mode 100644 vendor/github.com/segmentio/asm/base64/encode_amd64.s create mode 100644 vendor/github.com/segmentio/asm/base64/encode_arm64.go create mode 100644 vendor/github.com/segmentio/asm/base64/encode_arm64.s create mode 100644 vendor/github.com/segmentio/asm/cpu/arm/arm.go create mode 100644 vendor/github.com/segmentio/asm/cpu/arm64/arm64.go create mode 100644 vendor/github.com/segmentio/asm/cpu/cpu.go create mode 100644 vendor/github.com/segmentio/asm/cpu/cpuid/cpuid.go create mode 100644 vendor/github.com/segmentio/asm/cpu/x86/x86.go create mode 100644 vendor/github.com/segmentio/asm/internal/unsafebytes/unsafebytes.go rename vendor/github.com/sigstore/cosign/v2/{internal/pkg/now/now.go => cmd/cosign/cli/options/deprecate.go} (55%) create mode 100644 vendor/github.com/sigstore/rekor/pkg/pki/identity/identity.go create mode 100644 vendor/github.com/sigstore/sigstore/pkg/tuf/repository/targets/ctfe_2022.pub create mode 100644 vendor/github.com/sigstore/sigstore/pkg/tuf/repository/targets/fulcio_intermediate_v1.crt.pem delete mode 100644 vendor/github.com/sigstore/sigstore/pkg/tuf/repository/targets/rekor.0.pub delete mode 100644 vendor/github.com/sigstore/sigstore/pkg/tuf/repository/targets/rekor.json create mode 100644 vendor/github.com/sigstore/sigstore/pkg/tuf/repository/targets/trusted_root.json create mode 100644 vendor/github.com/sourcegraph/conc/.golangci.yml create mode 100644 vendor/github.com/sourcegraph/conc/LICENSE create mode 100644 vendor/github.com/sourcegraph/conc/README.md create mode 100644 vendor/github.com/sourcegraph/conc/internal/multierror/multierror_go119.go create mode 100644 vendor/github.com/sourcegraph/conc/internal/multierror/multierror_go120.go create mode 100644 vendor/github.com/sourcegraph/conc/iter/iter.go create mode 100644 vendor/github.com/sourcegraph/conc/iter/map.go create mode 100644 vendor/github.com/sourcegraph/conc/panics/panics.go create mode 100644 vendor/github.com/sourcegraph/conc/panics/try.go create mode 100644 vendor/github.com/sourcegraph/conc/waitgroup.go delete mode 100644 vendor/github.com/spf13/cobra/active_help.md delete mode 100644 vendor/github.com/spf13/cobra/bash_completions.md delete mode 100644 vendor/github.com/spf13/cobra/fish_completions.md delete mode 100644 vendor/github.com/spf13/cobra/powershell_completions.md delete mode 100644 vendor/github.com/spf13/cobra/projects_using_cobra.md delete mode 100644 vendor/github.com/spf13/cobra/shell_completions.md delete mode 100644 vendor/github.com/spf13/cobra/user_guide.md delete mode 100644 vendor/github.com/spf13/cobra/zsh_completions.md delete mode 100644 vendor/github.com/spf13/jwalterweatherman/README.md delete mode 100644 vendor/github.com/spf13/jwalterweatherman/default_notepad.go delete mode 100644 vendor/github.com/spf13/jwalterweatherman/log_counter.go delete mode 100644 vendor/github.com/spf13/jwalterweatherman/notepad.go create mode 100644 vendor/github.com/spf13/viper/.envrc create mode 100644 vendor/github.com/spf13/viper/.yamlignore create mode 100644 vendor/github.com/spf13/viper/.yamllint.yaml delete mode 100644 vendor/github.com/spf13/viper/experimental_logger.go create mode 100644 vendor/github.com/spf13/viper/flake.lock create mode 100644 vendor/github.com/spf13/viper/flake.nix delete mode 100644 vendor/github.com/spf13/viper/fs.go delete mode 100644 vendor/github.com/theupdateframework/go-tuf/pkg/deprecated/set_ecdsa/set_ecdsa.go create mode 100644 vendor/github.com/tinylib/msgp/LICENSE create mode 100644 vendor/github.com/tinylib/msgp/msgp/advise_linux.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/advise_other.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/circular.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/defs.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/edit.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/elsize.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/elsize_default.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/elsize_tinygo.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/errors.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/errors_default.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/errors_tinygo.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/extension.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/file.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/file_port.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/integers.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/json.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/json_bytes.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/number.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/purego.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/read.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/read_bytes.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/size.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/unsafe.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/write.go create mode 100644 vendor/github.com/tinylib/msgp/msgp/write_bytes.go create mode 100644 vendor/github.com/tjfoc/gmsm/sm3/ifile create mode 100644 vendor/github.com/xanzy/go-gitlab/appearance.go create mode 100644 vendor/github.com/xanzy/go-gitlab/group_epic_boards.go create mode 100644 vendor/github.com/xanzy/go-gitlab/group_protected_environments.go create mode 100644 vendor/github.com/xanzy/go-gitlab/group_repository_storage_move.go create mode 100644 vendor/github.com/xanzy/go-gitlab/job_token_scope.go create mode 100644 vendor/github.com/xanzy/go-gitlab/merge_trains.go create mode 100644 vendor/github.com/xanzy/go-gitlab/project_repository_storage_move.go create mode 100644 vendor/github.com/xanzy/go-gitlab/resource_iteration_events.go create mode 100644 vendor/github.com/xanzy/go-gitlab/snippet_repository_storage_move.go create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/doc.go create mode 100644 vendor/go.opentelemetry.io/otel/attribute/filter.go create mode 100644 vendor/go.opentelemetry.io/otel/internal/gen.go create mode 100644 vendor/go.uber.org/atomic/pointer_go118_pre119.go create mode 100644 vendor/go.uber.org/zap/.golangci.yml delete mode 100644 vendor/go.uber.org/zap/array_go118.go create mode 100644 vendor/go.uber.org/zap/internal/pool/pool.go rename vendor/go.uber.org/zap/{stacktrace.go => internal/stacktrace/stack.go} (73%) create mode 100644 vendor/go.uber.org/zap/zapcore/lazy_with.go create mode 100644 vendor/go4.org/intern/LICENSE create mode 100644 vendor/go4.org/intern/README.md create mode 100644 vendor/go4.org/intern/intern.go create mode 100644 vendor/go4.org/unsafe/assume-no-moving-gc/LICENSE create mode 100644 vendor/go4.org/unsafe/assume-no-moving-gc/README.md create mode 100644 vendor/go4.org/unsafe/assume-no-moving-gc/assume-no-moving-gc.go create mode 100644 vendor/go4.org/unsafe/assume-no-moving-gc/check.go create mode 100644 vendor/golang.org/x/exp/slices/cmp.go rename vendor/golang.org/x/exp/slices/{zsortfunc.go => zsortanyfunc.go} (64%) create mode 100644 vendor/golang.org/x/exp/slog/attr.go create mode 100644 vendor/golang.org/x/exp/slog/doc.go create mode 100644 vendor/golang.org/x/exp/slog/handler.go create mode 100644 vendor/golang.org/x/exp/slog/internal/buffer/buffer.go create mode 100644 vendor/golang.org/x/exp/slog/internal/ignorepc.go create mode 100644 vendor/golang.org/x/exp/slog/json_handler.go create mode 100644 vendor/golang.org/x/exp/slog/level.go create mode 100644 vendor/golang.org/x/exp/slog/logger.go create mode 100644 vendor/golang.org/x/exp/slog/noplog.bench create mode 100644 vendor/golang.org/x/exp/slog/record.go create mode 100644 vendor/golang.org/x/exp/slog/text_handler.go create mode 100644 vendor/golang.org/x/exp/slog/value.go create mode 100644 vendor/golang.org/x/exp/slog/value_119.go create mode 100644 vendor/golang.org/x/exp/slog/value_120.go create mode 100644 vendor/golang.org/x/oauth2/deviceauth.go create mode 100644 vendor/golang.org/x/oauth2/google/internal/externalaccount/header.go create mode 100644 vendor/golang.org/x/oauth2/google/internal/externalaccountauthorizeduser/externalaccountauthorizeduser.go rename vendor/golang.org/x/oauth2/google/internal/{externalaccount => stsexchange}/clientauth.go (88%) rename vendor/golang.org/x/oauth2/google/internal/{externalaccount => stsexchange}/sts_exchange.go (68%) create mode 100644 vendor/golang.org/x/oauth2/pkce.go create mode 100644 vendor/golang.org/x/sys/windows/registry/key.go create mode 100644 vendor/golang.org/x/sys/windows/registry/mksyscall.go create mode 100644 vendor/golang.org/x/sys/windows/registry/syscall.go create mode 100644 vendor/golang.org/x/sys/windows/registry/value.go create mode 100644 vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go create mode 100644 vendor/golang.org/x/tools/go/types/objectpath/objectpath.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/objectpath.go create mode 100644 vendor/golang.org/x/xerrors/LICENSE create mode 100644 vendor/golang.org/x/xerrors/PATENTS create mode 100644 vendor/golang.org/x/xerrors/README create mode 100644 vendor/golang.org/x/xerrors/adaptor.go create mode 100644 vendor/golang.org/x/xerrors/codereview.cfg create mode 100644 vendor/golang.org/x/xerrors/doc.go create mode 100644 vendor/golang.org/x/xerrors/errors.go create mode 100644 vendor/golang.org/x/xerrors/fmt.go create mode 100644 vendor/golang.org/x/xerrors/format.go create mode 100644 vendor/golang.org/x/xerrors/frame.go create mode 100644 vendor/golang.org/x/xerrors/internal/internal.go create mode 100644 vendor/golang.org/x/xerrors/wrap.go delete mode 100644 vendor/google.golang.org/api/transport/http/dial_appengine.go delete mode 100644 vendor/google.golang.org/appengine/.travis.yml delete mode 100644 vendor/google.golang.org/appengine/internal/socket/socket_service.pb.go delete mode 100644 vendor/google.golang.org/appengine/internal/socket/socket_service.proto delete mode 100644 vendor/google.golang.org/appengine/socket/doc.go delete mode 100644 vendor/google.golang.org/appengine/socket/socket_classic.go delete mode 100644 vendor/google.golang.org/appengine/socket/socket_vm.go delete mode 100644 vendor/google.golang.org/appengine/travis_install.sh delete mode 100644 vendor/google.golang.org/appengine/travis_test.sh create mode 100644 vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go rename vendor/google.golang.org/grpc/{ => internal/idle}/idle.go (61%) create mode 100644 vendor/google.golang.org/grpc/shared_buffer_pool.go delete mode 100644 vendor/google.golang.org/protobuf/types/known/emptypb/empty.pb.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/LICENSE create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/LICENSE-3rdparty.csv create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/LICENSE-APACHE create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/LICENSE-BSD3 create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/NOTICE create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/datastreams/options/options.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ddtrace.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/app_types.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/db.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/messaging.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/peer.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/priority.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/rpc.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/span_kind.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/system.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/tags.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/internal/globaltracer.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/abandonedspans.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/context.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/data_streams.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/doc.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/log.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/metrics.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/option.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/payload.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/propagating_tags.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/propagator.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/rand.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/rules_sampler.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/sampler.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/span.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/span_msgp.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/spancontext.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/sqlcomment.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/stats.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/stats_payload.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/stats_payload_msgp.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/telemetry.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/textmap.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/time.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/time_windows.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/tracer.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/transport.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/util.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/writer.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/active_span_key.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/agent.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/appsec.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/appsec_disabled.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/config.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo/instrumentation/common.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo/instrumentation/grpcsec/grpc.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo/instrumentation/grpcsec/tags.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo/instrumentation/httpsec/http.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo/instrumentation/httpsec/tags.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo/instrumentation/sharedsec/actions.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo/instrumentation/sharedsec/blocked-template.html create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo/instrumentation/sharedsec/blocked-template.json create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo/instrumentation/sharedsec/shared.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo/operation.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/limiter.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/remoteconfig.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/rules.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/rules.json create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/rules_manager.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/waf.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/container.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams/pathway.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams/payload.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams/payload_msgp.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams/processor.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams/propagator.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams/transport.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/env.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/gitmetadata.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/gitmetadatabinary.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/gitmetadatabinary_legacy.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig/globalconfig.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/azure/azure.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/cachedfetch/fetcher.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/ec2/ec2.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/ecs/aws.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/fqdn_nix.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/fqdn_windows.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/gce/gce.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/httputils/helpers.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/providers.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/validate/validate.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/log/log.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema/namingschema.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema/op_cache.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema/op_client_server.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema/op_db.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema/op_messaging.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema/option.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema/service_name.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/normalizer/normalizer.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo/osinfo.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo/osinfo_darwin.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo/osinfo_default.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo/osinfo_freebsd.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo/osinfo_linux.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo/osinfo_windows.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/remoteconfig/config.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/remoteconfig/remoteconfig.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/remoteconfig/types.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/samplernames/samplernames.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/statsd.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry/client.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry/message.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry/option.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry/telemetry.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry/utils.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/trace_context.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/traceprof/endpoint_counter.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/traceprof/profiler.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/traceprof/traceprof.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/utils.go create mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/version/version.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/.gitcookies.sh.enc create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/.gitignore create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/.travis.yml create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/CONTRIBUTING.md create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/LICENSE create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/README.md create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/asymmetric.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/cipher/cbc_hmac.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/cipher/concat_kdf.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/cipher/ecdh_es.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/cipher/key_wrap.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/crypter.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/doc.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/encoding.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/json/LICENSE create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/json/README.md create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/json/decode.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/json/encode.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/json/indent.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/json/scanner.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/json/stream.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/json/tags.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/jwe.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/jwk.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/jws.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/opaque.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/shared.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/signing.go create mode 100644 vendor/gopkg.in/go-jose/go-jose.v2/symmetric.go create mode 100644 vendor/inet.af/netaddr/.gitignore create mode 100644 vendor/inet.af/netaddr/.gitmodules create mode 100644 vendor/inet.af/netaddr/AUTHORS create mode 100644 vendor/inet.af/netaddr/LICENSE create mode 100644 vendor/inet.af/netaddr/README.md create mode 100644 vendor/inet.af/netaddr/fuzz.go create mode 100644 vendor/inet.af/netaddr/ipset.go create mode 100644 vendor/inet.af/netaddr/mask6.go create mode 100644 vendor/inet.af/netaddr/netaddr.go create mode 100644 vendor/inet.af/netaddr/uint128.go create mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/splice.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/dump/dump.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versioncheck.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/variable.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/auditannotation.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/expressionwarning.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchresources.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/namedrulewithoperations.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/paramkind.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/paramref.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/typechecking.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicy.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicybinding.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicybindingspec.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicyspec.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingadmissionpolicystatus.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validation.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/variable.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/core/v1/hostip.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/core/v1/podresourceclaimstatus.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/networkpolicystatus.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1alpha1/exemptprioritylevelconfiguration.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta1/exemptprioritylevelconfiguration.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta2/exemptprioritylevelconfiguration.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3/exemptprioritylevelconfiguration.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/networking/v1/networkpolicystatus.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1/validatingadmissionpolicy.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1/validatingadmissionpolicybinding.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/authentication/v1/selfsubjectreview.go create mode 100644 vendor/k8s.io/client-go/openapi/typeconverter.go create mode 100644 vendor/k8s.io/client-go/tools/cache/object-names.go delete mode 100644 vendor/k8s.io/client-go/tools/leaderelection/resourcelock/configmaplock.go delete mode 100644 vendor/k8s.io/client-go/tools/leaderelection/resourcelock/endpointslock.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/builder3/util/util.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/openapiconv/convert.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/schemamutation/walker.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/spec/fuzz.go create mode 100644 vendor/k8s.io/utils/ptr/OWNERS create mode 100644 vendor/k8s.io/utils/ptr/README.md create mode 100644 vendor/k8s.io/utils/ptr/ptr.go create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/LICENSE create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/LICENSE.libyaml create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/NOTICE create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/OWNERS create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/README.md create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/apic.go create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/decode.go create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/emitterc.go create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/encode.go create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/parserc.go create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/readerc.go create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/resolve.go create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/scannerc.go create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/sorter.go create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/writerc.go create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/yaml.go create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/yamlh.go create mode 100644 vendor/sigs.k8s.io/yaml/goyaml.v2/yamlprivateh.go diff --git a/go.mod b/go.mod index e794d134f..cfe07fa6f 100644 --- a/go.mod +++ b/go.mod @@ -6,17 +6,17 @@ require ( github.com/Masterminds/sprig/v3 v3.2.3 github.com/ahmetb/gen-crd-api-reference-docs v0.3.0 github.com/containerd/containerd v1.7.0 - github.com/docker/cli v23.0.5+incompatible + github.com/docker/cli v24.0.7+incompatible github.com/gardener/component-cli v0.44.0 github.com/gardener/component-spec/bindings-go v0.0.95 github.com/gardener/image-vector v0.10.0 github.com/gardener/landscaper/apis v0.0.0-00010101000000-000000000000 github.com/gardener/landscaper/controller-utils v0.0.0-00010101000000-000000000000 - github.com/go-logr/logr v1.2.4 + github.com/go-logr/logr v1.3.0 github.com/golang/mock v1.6.0 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.4.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/imdario/mergo v0.3.15 + github.com/imdario/mergo v0.3.16 github.com/mandelsoft/filepath v0.0.0-20230412200429-36b1eb66bd27 github.com/mandelsoft/spiff v1.7.0-beta-5 github.com/mandelsoft/vfs v0.0.0-20230713123140-269aa4fb1338 @@ -25,125 +25,137 @@ require ( github.com/onsi/gomega v1.27.7 github.com/open-component-model/ocm v0.4.1 github.com/opencontainers/go-digest v1.0.0 - github.com/opencontainers/image-spec v1.1.0-rc3 + github.com/opencontainers/image-spec v1.1.0-rc5 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.15.1 + github.com/prometheus/client_golang v1.17.0 github.com/robfig/cron/v3 v3.0.1 - github.com/spf13/cobra v1.7.0 + github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/xeipuuv/gojsonschema v1.2.0 golang.org/x/crypto v0.14.0 golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 - golang.org/x/oauth2 v0.9.0 - golang.org/x/sync v0.3.0 + golang.org/x/oauth2 v0.13.0 + golang.org/x/sync v0.5.0 golang.org/x/sys v0.13.0 gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.12.2 - k8s.io/api v0.27.3 + k8s.io/api v0.28.3 k8s.io/apiextensions-apiserver v0.27.2 - k8s.io/apimachinery v0.27.3 - k8s.io/client-go v0.27.3 - k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 + k8s.io/apimachinery v0.28.3 + k8s.io/client-go v0.28.3 + k8s.io/utils v0.0.0-20230726121419-3b25d923346b sigs.k8s.io/controller-runtime v0.15.1 - sigs.k8s.io/yaml v1.3.0 + sigs.k8s.io/yaml v1.4.0 ) require ( - cloud.google.com/go/compute v1.19.3 // indirect + cloud.google.com/go/compute v1.23.2 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudsdkgo/helper v0.2.0 // indirect github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect - github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.29 // indirect - github.com/Azure/go-autorest/autorest/adal v0.9.22 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 // indirect github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/BurntSushi/toml v1.2.1 // indirect - github.com/DataDog/gostackparse v0.6.0 // indirect + github.com/DataDog/appsec-internal-go v1.0.0 // indirect + github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.1 // indirect + github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.1 // indirect + github.com/DataDog/datadog-go/v5 v5.3.0 // indirect + github.com/DataDog/go-libddwaf v1.5.0 // indirect + github.com/DataDog/go-tuf v1.0.2-0.5.2 // indirect + github.com/DataDog/gostackparse v0.7.0 // indirect + github.com/DataDog/sketches-go v1.4.3 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/squirrel v1.5.4 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c // indirect github.com/ThalesIgnite/crypto11 v1.2.5 // indirect github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect github.com/alibabacloud-go/cr-20160607 v1.0.1 // indirect github.com/alibabacloud-go/cr-20181201 v1.0.10 // indirect - github.com/alibabacloud-go/darabonba-openapi v0.1.18 // indirect - github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 // indirect + github.com/alibabacloud-go/darabonba-openapi v0.2.1 // indirect + github.com/alibabacloud-go/debug v1.0.0 // indirect github.com/alibabacloud-go/endpoint-util v1.1.1 // indirect - github.com/alibabacloud-go/openapi-util v0.0.11 // indirect - github.com/alibabacloud-go/tea v1.1.18 // indirect - github.com/alibabacloud-go/tea-utils v1.4.4 // indirect - github.com/alibabacloud-go/tea-xml v1.1.2 // indirect - github.com/aliyun/credentials-go v1.2.3 // indirect + github.com/alibabacloud-go/openapi-util v0.1.0 // indirect + github.com/alibabacloud-go/tea v1.2.1 // indirect + github.com/alibabacloud-go/tea-utils v1.4.5 // indirect + github.com/alibabacloud-go/tea-xml v1.1.3 // indirect + github.com/aliyun/credentials-go v1.3.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go-v2 v1.18.1 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.8 // indirect - github.com/aws/aws-sdk-go-v2/config v1.18.27 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.13.26 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4 // indirect + github.com/aws/aws-sdk-go-v2 v1.21.2 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 // indirect + github.com/aws/aws-sdk-go-v2/config v1.19.1 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.13.43 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 // indirect github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.33 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14 // indirect - github.com/aws/aws-sdk-go-v2/service/ecr v1.18.7 // indirect - github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.12.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.18 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.17 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.27.11 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.12.12 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 // indirect - github.com/aws/smithy-go v1.13.5 // indirect - github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20220228164355-396b2034c795 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4 // indirect + github.com/aws/aws-sdk-go-v2/service/ecr v1.20.2 // indirect + github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.40.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.15.2 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.23.2 // indirect + github.com/aws/smithy-go v1.15.0 // indirect + github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect - github.com/buildkite/agent/v3 v3.49.0 // indirect + github.com/buildkite/agent/v3 v3.58.0 // indirect + github.com/buildkite/interpolate v0.0.0-20200526001904-07f35b4ae251 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect - github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21 // indirect - github.com/clbanning/mxj/v2 v2.5.6 // indirect - github.com/cloudflare/circl v1.3.3 // indirect + github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 // indirect + github.com/clbanning/mxj/v2 v2.7.0 // indirect + github.com/cloudflare/circl v1.3.5 // indirect github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect github.com/containers/image/v5 v5.21.1 // indirect github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a // indirect github.com/containers/ocicrypt v1.1.6 // indirect github.com/containers/storage v1.42.0 // indirect - github.com/coreos/go-oidc/v3 v3.6.0 // indirect - github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7 // indirect + github.com/coreos/go-oidc/v3 v3.7.0 // indirect + github.com/cyberphone/json-canonicalization v0.0.0-20231011164504-785e29786b46 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/digitorus/pkcs7 v0.0.0-20221212123742-001c36b64ec3 // indirect - github.com/digitorus/timestamp v0.0.0-20221019182153-ef3b63b79b31 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect + github.com/digitorus/timestamp v0.0.0-20230902153158-687734543647 // indirect github.com/dimchansky/utfbom v1.1.1 // indirect - github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker v23.0.5+incompatible // indirect - github.com/docker/docker-credential-helpers v0.7.0 // indirect + github.com/distribution/reference v0.5.0 // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker v24.0.7+incompatible // indirect + github.com/docker/docker-credential-helpers v0.8.0 // indirect github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/drone/envsubst v1.0.3 // indirect - github.com/emicklei/go-restful/v3 v3.10.1 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/ebitengine/purego v0.5.0 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect - github.com/fatih/color v1.13.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fatih/color v1.15.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fvbommel/sortorder v1.0.2 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-chi/chi v4.1.2+incompatible // indirect github.com/go-errors/errors v1.4.2 // indirect @@ -152,8 +164,8 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.2.4 // indirect github.com/go-openapi/analysis v0.21.4 // indirect - github.com/go-openapi/errors v0.20.3 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/errors v0.20.4 // indirect + github.com/go-openapi/jsonpointer v0.20.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/loads v0.21.2 // indirect github.com/go-openapi/runtime v0.26.0 // indirect @@ -163,49 +175,58 @@ require ( github.com/go-openapi/validate v0.22.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.14.0 // indirect + github.com/go-playground/validator/v10 v10.15.5 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/go-test/deep v1.1.0 // indirect github.com/gobwas/glob v0.2.3 // indirect + github.com/goccy/go-json v0.10.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect - github.com/google/certificate-transparency-go v1.1.6 // indirect + github.com/google/certificate-transparency-go v1.1.7 // indirect github.com/google/gnostic v0.6.9 // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/google/go-containerregistry v0.15.2 // indirect + github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-containerregistry v0.16.1 // indirect github.com/google/go-github/v45 v45.2.0 // indirect - github.com/google/go-github/v50 v50.2.0 // indirect + github.com/google/go-github/v55 v55.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20221103000818-d260c55eee4c // indirect - github.com/google/s2a-go v0.1.4 // indirect + github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect + github.com/google/s2a-go v0.1.7 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.4 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gosuri/uitable v0.0.4 // indirect + github.com/gowebpki/jcs v1.0.1 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-retryablehttp v0.7.2 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hashicorp/go-retryablehttp v0.7.4 // indirect + github.com/hashicorp/hcl v1.0.1-vault-5 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/in-toto/in-toto-golang v0.9.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b // indirect + github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmoiron/sqlx v1.3.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.16.5 // indirect - github.com/klauspost/pgzip v1.2.5 // indirect + github.com/klauspost/compress v1.17.2 // indirect + github.com/klauspost/pgzip v1.2.6 // indirect github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/leodido/go-urn v1.2.4 // indirect - github.com/letsencrypt/boulder v0.0.0-20221109233200-85aa52084eaf // indirect + github.com/lestrrat-go/blackmagic v1.0.2 // indirect + github.com/lestrrat-go/httpcc v1.0.1 // indirect + github.com/lestrrat-go/httprc v1.0.4 // indirect + github.com/lestrrat-go/iter v1.0.2 // indirect + github.com/lestrrat-go/jwx/v2 v2.0.16 // indirect + github.com/lestrrat-go/option v1.0.1 // indirect + github.com/letsencrypt/boulder v0.0.0-20231026200631-000cd05d5491 // indirect github.com/lib/pq v1.10.9 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -213,9 +234,9 @@ require ( github.com/mandelsoft/logging v0.0.0-20230905123808-7042ee3aae45 // indirect github.com/marstr/guid v1.1.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -235,95 +256,109 @@ require ( github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/oklog/ulid v1.3.1 // indirect + github.com/oleiade/reflections v1.0.1 // indirect github.com/opencontainers/distribution-spec v1.0.1 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/outcaste-io/ristretto v0.2.3 // indirect github.com/pborman/uuid v1.2.1 // indirect github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect - github.com/rivo/uniseg v0.4.2 // indirect + github.com/philhofer/fwd v1.1.2 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect + github.com/rivo/uniseg v0.4.4 // indirect github.com/rubenv/sql-migrate v1.3.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sagikazarmark/locafero v0.3.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sassoftware/relic v7.2.1+incompatible // indirect - github.com/secure-systems-lab/go-securesystemslib v0.6.0 // indirect + github.com/secure-systems-lab/go-securesystemslib v0.7.0 // indirect + github.com/segmentio/asm v1.2.0 // indirect github.com/segmentio/ksuid v1.0.4 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect - github.com/sigstore/cosign/v2 v2.1.1 // indirect - github.com/sigstore/fulcio v1.3.1 // indirect - github.com/sigstore/rekor v1.2.2-0.20230530122220-67cc9e58bd23 // indirect - github.com/sigstore/sigstore v1.7.1 // indirect - github.com/sigstore/timestamp-authority v1.1.1 // indirect + github.com/sigstore/cosign/v2 v2.2.1 // indirect + github.com/sigstore/fulcio v1.4.3 // indirect + github.com/sigstore/rekor v1.3.3 // indirect + github.com/sigstore/sigstore v1.7.5 // indirect + github.com/sigstore/timestamp-authority v1.2.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect - github.com/spf13/afero v1.9.5 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.10.0 // indirect github.com/spf13/cast v1.5.1 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/viper v1.16.0 // indirect + github.com/spf13/viper v1.17.0 // indirect github.com/spiffe/go-spiffe/v2 v2.1.6 // indirect - github.com/subosito/gotenv v1.4.2 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/thales-e-security/pool v0.0.2 // indirect - github.com/theupdateframework/go-tuf v0.5.2 // indirect + github.com/theupdateframework/go-tuf v0.6.1 // indirect github.com/theupdateframework/notary v0.7.0 // indirect + github.com/tinylib/msgp v1.1.8 // indirect github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect - github.com/tjfoc/gmsm v1.3.2 // indirect + github.com/tjfoc/gmsm v1.4.1 // indirect github.com/tonglil/buflogr v1.0.1 // indirect github.com/transparency-dev/merkle v0.0.2 // indirect - github.com/ulikunitz/xz v0.5.10 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - github.com/vbatts/tar-split v0.11.3 // indirect - github.com/xanzy/go-gitlab v0.86.0 // indirect + github.com/vbatts/tar-split v0.11.5 // indirect + github.com/xanzy/go-gitlab v0.93.2 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xlab/treeprint v1.1.0 // indirect github.com/zeebo/errs v1.3.0 // indirect - go.mongodb.org/mongo-driver v1.11.3 // indirect + go.mongodb.org/mongo-driver v1.12.1 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.16.0 // indirect - go.opentelemetry.io/otel/metric v1.16.0 // indirect - go.opentelemetry.io/otel/trace v1.16.0 // indirect + go.opentelemetry.io/otel v1.19.0 // indirect + go.opentelemetry.io/otel/metric v1.19.0 // indirect + go.opentelemetry.io/otel/trace v1.19.0 // indirect go.starlark.net v0.0.0-20221028183056-acb66ad56dd2 // indirect - go.step.sm/crypto v0.32.1 // indirect - go.uber.org/atomic v1.10.0 // indirect + go.step.sm/crypto v0.36.1 // indirect + go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.24.0 // indirect - golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect - golang.org/x/mod v0.11.0 // indirect + go.uber.org/zap v1.26.0 // indirect + go4.org/intern v0.0.0-20230525184215-6c62f75575cb // indirect + go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 // indirect + golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect + golang.org/x/mod v0.13.0 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.9.3 // indirect + golang.org/x/tools v0.14.0 // indirect + golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect - google.golang.org/api v0.128.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect - google.golang.org/grpc v1.56.3 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/api v0.149.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect + google.golang.org/grpc v1.59.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/DataDog/dd-trace-go.v1 v1.56.1 // indirect + gopkg.in/go-jose/go-jose.v2 v2.6.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect + inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a // indirect k8s.io/apiserver v0.27.2 // indirect k8s.io/cli-runtime v0.27.2 // indirect k8s.io/component-base v0.27.2 // indirect - k8s.io/gengo v0.0.0-20220902162205-c0856e24416d // indirect + k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 // indirect k8s.io/klog v1.0.0 // indirect k8s.io/klog/v2 v2.100.1 // indirect - k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect + k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect k8s.io/kubectl v0.27.2 // indirect oras.land/oras-go v1.2.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.13.2 // indirect sigs.k8s.io/kustomize/kyaml v0.14.1 // indirect - sigs.k8s.io/release-utils v0.7.4 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/release-utils v0.7.6 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect ) replace ( diff --git a/go.sum b/go.sum index b46492cc1..45208b409 100644 --- a/go.sum +++ b/go.sum @@ -22,22 +22,22 @@ cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPT cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= +cloud.google.com/go v0.110.9 h1:e7ITSqGFFk4rbz/JFIqZh3G4VEHguhAL4BQcFlWtU68= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.19.3 h1:DcTwsFgGev/wV5+q8o2fzgcHOaac+DKGC91ZlvpsQds= -cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= +cloud.google.com/go/compute v1.23.2 h1:nWEMDhgbBkBJjfpVySqU4jgWdc22PLR0o4vEexZHers= +cloud.google.com/go/compute v1.23.2/go.mod h1:JJ0atRC0J/oWYiiVBmsSsrRnh92DhZPG4hFDcR04Rns= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/iam v1.1.0 h1:67gSqaPukx7O8WLLHMa0PNs3EBGd2eE4d+psbO/CO94= -cloud.google.com/go/kms v1.12.1 h1:xZmZuwy2cwzsocmKDOPu4BL7umg8QXagQx6fKVmf45U= +cloud.google.com/go/iam v1.1.4 h1:K6n/GZHFTtEoKT5aUG3l9diPi0VduZNQ1PfdnpkkIFk= +cloud.google.com/go/kms v1.15.4 h1:gEZzC54ZBI+aeW8/jg9tgz9KR4Aa+WEDPbdGIV3iJ7A= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -55,43 +55,39 @@ github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774/go.mod h1:6/0dY github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0= -github.com/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230329111138-12e09aba5ebd h1:1tbEqR4NyQLgiod7vLXSswHteGetAVZrMGCqrJxLKRs= +github.com/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230618160516-e936619f9f18 h1:rd389Q26LMy03gG4anandGFC2LW/xvjga5GezeeaxQk= github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudsdkgo/helper v0.2.0 h1:8+4G8JaejP8Xa6W46PzJEwisNgBXMvFcz78N6zG/ARw= github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudsdkgo/helper v0.2.0/go.mod h1:GgeIE+1be8Ivm7Sh4RgwI42aTtC9qrcj+Y9Y6CjJhJs= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v46.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1 h1:SEy2xmstIphdPwNBUi7uhvjyjhVKISfwjfOJmuy7kg4= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v0.12.0 h1:4Kynh6Hn2ekyIsBgNQJb3dn1+/MyvzfUJebti2emB/A= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 h1:T028gtTPiYt/RMUfs8nVsAL7FDQrfLlrm/NnRG/zcC4= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 h1:9kDVnTz3vbfweTqAUmk/a/pH5pWFCHtvRpHYC0G/dcA= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.4.0 h1:TuEMD+E+1aTjjLICGQOW6vLe8UWES7kopac9mUXL56Y= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 h1:MyVTgWR8qd/Jw1Le0NZebGBUCLbtak3bJ3z1OlqZBpw= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 h1:D3occbWoio4EBLkbkevetNMAVX197GkzbUMtqjGWn80= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= -github.com/Azure/go-autorest/autorest v0.11.6/go.mod h1:V6p3pKZx1KKkJubbxnDWrzNhEIfOy/pTGasLqzHIPHs= -github.com/Azure/go-autorest/autorest v0.11.8/go.mod h1:V6p3pKZx1KKkJubbxnDWrzNhEIfOy/pTGasLqzHIPHs= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw= github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= -github.com/Azure/go-autorest/autorest/adal v0.9.4/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/adal v0.9.22 h1:/GblQdIudfEM3AWWZ0mrYJQSd7JS4S/Mbzh6F0ov0Xc= github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.2/go.mod h1:q98IH4qgc3eWM4/WOeR5+YPmBuy8Lq0jNRDwSM0CuFk= +github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= +github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 h1:wkAZRgT/pn8HhFyzfe9UnqOjJYqlembgCTi72Bm/xKk= github.com/Azure/go-autorest/autorest/azure/auth v0.5.12/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.1/go.mod h1:JfDgiIO1/RPu6z42AdQTyjOoCM2MFhLqSBDvMEkDgcg= github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg= github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 h1:w77/uPk80ZET2F+AfQExZyEWtn+0Rk/uw17m9fv5Ajc= github.com/Azure/go-autorest/autorest/azure/cli v0.4.6/go.mod h1:piCfgPho7BiIDdEQ1+g4VmKyD5y+p/XtSNqE6Hc4QD0= @@ -106,7 +102,7 @@ github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+Z github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkMqLPymWEppkm7vgPQY2XsHoEkaMQ0AdZY= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 h1:hVeq+yCyUi+MsoO/CU95yqCIcdzra5ovzk8Q2BBpV2M= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -114,8 +110,22 @@ github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/DataDog/gostackparse v0.6.0 h1:egCGQviIabPwsyoWpGvIBGrEnNWez35aEO7OJ1vBI4o= -github.com/DataDog/gostackparse v0.6.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= +github.com/DataDog/appsec-internal-go v1.0.0 h1:2u5IkF4DBj3KVeQn5Vg2vjPUtt513zxEYglcqnd500U= +github.com/DataDog/appsec-internal-go v1.0.0/go.mod h1:+Y+4klVWKPOnZx6XESG7QHydOaUGEXyH2j/vSg9JiNM= +github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.1 h1:uS2NzlwpCs+ZBHE9MLK1tGgxJOe2fVbwwjEEu34Kll4= +github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.1/go.mod h1:HzySONXnAgSmIQfL6gOv9hWprKJkx8CicuXuUbmgWfo= +github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.1 h1:5nE6N3JSs2IG3xzMthNFhXfOaXlrsdgqmJ73lndFf8c= +github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.1/go.mod h1:Vc+snp0Bey4MrrJyiV2tVxxJb6BmLomPvN1RgAvjGaQ= +github.com/DataDog/datadog-go/v5 v5.3.0 h1:2q2qjFOb3RwAZNU+ez27ZVDwErJv5/VpbBPprz7Z+s8= +github.com/DataDog/datadog-go/v5 v5.3.0/go.mod h1:XRDJk1pTc00gm+ZDiBKsjh7oOOtJfYfglVCmFb8C2+Q= +github.com/DataDog/go-libddwaf v1.5.0 h1:lrHP3VrEriy1M5uQuaOcKphf5GU40mBhihMAp6Ik55c= +github.com/DataDog/go-libddwaf v1.5.0/go.mod h1:Fpnmoc2k53h6desQrH1P0/gR52CUzkLNFugE5zWwUBQ= +github.com/DataDog/go-tuf v1.0.2-0.5.2 h1:EeZr937eKAWPxJ26IykAdWA4A0jQXJgkhUjqEI/w7+I= +github.com/DataDog/go-tuf v1.0.2-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0= +github.com/DataDog/gostackparse v0.7.0 h1:i7dLkXHvYzHV308hnkvVGDL3BR4FWl7IsXNPz/IGQh4= +github.com/DataDog/gostackparse v0.7.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= +github.com/DataDog/sketches-go v1.4.3 h1:ZB9nijteJRFUQixkQfatCqASartGNfiolIlMiEv3u/w= +github.com/DataDog/sketches-go v1.4.3/go.mod h1:XR0ns2RtEEF09mDKXiKZiQg+nfZStrq1ZuL1eezeZe0= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -137,6 +147,7 @@ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugX github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= @@ -160,8 +171,8 @@ github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb0 github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/ProtonMail/go-crypto v0.0.0-20220407094043-a94812496cf5/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= -github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 h1:ZK3C5DtzV2nVAQTx5S5jQvMeDqWtD1By5mOoyY/xJek= -github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE= +github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c h1:kMFnB0vCcX7IL/m9Y5LO+KQYv+t1CQOiFe6+SV2J7bE= +github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= @@ -181,6 +192,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.2/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc= @@ -192,35 +204,39 @@ github.com/alibabacloud-go/cr-20181201 v1.0.10 h1:B60f6S1imsgn2fgC6X6FrVNrONDrbC github.com/alibabacloud-go/cr-20181201 v1.0.10/go.mod h1:VN9orB/w5G20FjytoSpZROqu9ZqxwycASmGqYUJSoDc= github.com/alibabacloud-go/darabonba-openapi v0.1.12/go.mod h1:sTAjsFJmVsmcVeklL9d9uDBlFsgl43wZ6jhI6BHqHqU= github.com/alibabacloud-go/darabonba-openapi v0.1.14/go.mod h1:w4CosR7O/kapCtEEMBm3JsQqWBU/CnZ2o0pHorsTWDI= -github.com/alibabacloud-go/darabonba-openapi v0.1.18 h1:3eUVmAr7WCJp7fgIvmCd9ZUyuwtJYbtUqJIed5eXCmk= -github.com/alibabacloud-go/darabonba-openapi v0.1.18/go.mod h1:PB4HffMhJVmAgNKNq3wYbTUlFvPgxJpTzd1F5pTuUsc= +github.com/alibabacloud-go/darabonba-openapi v0.2.1 h1:WyzxxKvhdVDlwpAMOHgAiCJ+NXa6g5ZWPFEzaK/ewwY= +github.com/alibabacloud-go/darabonba-openapi v0.2.1/go.mod h1:zXOqLbpIqq543oioL9IuuZYOQgHQ5B8/n5OPrnko8aY= github.com/alibabacloud-go/darabonba-string v1.0.0/go.mod h1:93cTfV3vuPhhEwGGpKKqhVW4jLe7tDpo3LUM0i0g6mA= -github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 h1:NqugFkGxx1TXSh/pBcU00Y6bljgDPaFdh5MUSeJ7e50= github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY= +github.com/alibabacloud-go/debug v1.0.0 h1:3eIEQWfay1fB24PQIEzXAswlVJtdQok8f3EVN5VrBnA= +github.com/alibabacloud-go/debug v1.0.0/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc= github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE= github.com/alibabacloud-go/endpoint-util v1.1.1 h1:ZkBv2/jnghxtU0p+upSU0GGzW1VL9GQdZO3mcSUTUy8= github.com/alibabacloud-go/endpoint-util v1.1.1/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE= github.com/alibabacloud-go/openapi-util v0.0.9/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= github.com/alibabacloud-go/openapi-util v0.0.10/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= -github.com/alibabacloud-go/openapi-util v0.0.11 h1:iYnqOPR5hyEEnNZmebGyRMkkEJRWUEjDiiaOHZ5aNhA= github.com/alibabacloud-go/openapi-util v0.0.11/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= +github.com/alibabacloud-go/openapi-util v0.1.0 h1:0z75cIULkDrdEhkLWgi9tnLe+KhAFE/r5Pb3312/eAY= +github.com/alibabacloud-go/openapi-util v0.1.0/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= github.com/alibabacloud-go/tea v1.1.0/go.mod h1:IkGyUSX4Ba1V+k4pCtJUc6jDpZLFph9QMy2VUPTwukg= github.com/alibabacloud-go/tea v1.1.7/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= github.com/alibabacloud-go/tea v1.1.11/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A= -github.com/alibabacloud-go/tea v1.1.18 h1:+6GJ06eu5Cr/Mkj09vWrf6QAfrPepctY2OxcWNclRC0= -github.com/alibabacloud-go/tea v1.1.18/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A= +github.com/alibabacloud-go/tea v1.1.19/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A= +github.com/alibabacloud-go/tea v1.2.1 h1:rFF1LnrAdhaiPmKwH5xwYOKlMh66CqRwPUTzIK74ask= +github.com/alibabacloud-go/tea v1.2.1/go.mod h1:qbzof29bM/IFhLMtJPrgTGK3eauV5J2wSyEUo4OEmnA= github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE= github.com/alibabacloud-go/tea-utils v1.3.9/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE= github.com/alibabacloud-go/tea-utils v1.4.3/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw= -github.com/alibabacloud-go/tea-utils v1.4.4 h1:lxCDvNCdTo9FaXKKq45+4vGETQUKNOW/qKTcX9Sk53o= -github.com/alibabacloud-go/tea-utils v1.4.4/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw= -github.com/alibabacloud-go/tea-xml v1.1.2 h1:oLxa7JUXm2EDFzMg+7oRsYc+kutgCVwm+bZlhhmvW5M= +github.com/alibabacloud-go/tea-utils v1.4.5 h1:h0/6Xd2f3bPE4XHTvkpjwxowIwRCJAJOqY6Eq8f3zfA= +github.com/alibabacloud-go/tea-utils v1.4.5/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw= github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8= +github.com/alibabacloud-go/tea-xml v1.1.3 h1:7LYnm+JbOq2B+T/B0fHC4Ies4/FofC4zHzYtqw7dgt0= +github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8= github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw= -github.com/aliyun/credentials-go v1.2.3 h1:Vmodnr52Rz1mcbwn0kzMhLRKb6soizewuKXdfZiNemU= -github.com/aliyun/credentials-go v1.2.3/go.mod h1:/KowD1cfGSLrLsH28Jr8W+xwoId0ywIy5lNzDz6O1vw= +github.com/aliyun/credentials-go v1.3.1 h1:uq/0v7kWrxmoLGpqjx7vtQ/s03f0zR//0br/xWDTE28= +github.com/aliyun/credentials-go v1.3.1/go.mod h1:8jKYhQuDawt8x2+fusqa1Y6mPxemTsBEN04dgcAcYz0= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -233,85 +249,77 @@ github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:W github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.44.288 h1:Ln7fIao/nl0ACtelgR1I4AiEw/GLNkKcXfCaHupUW5Q= -github.com/aws/aws-sdk-go-v2 v1.7.1/go.mod h1:L5LuPC1ZgDr2xQS7AmIec/Jlc7O/Y1u2KxJyNVab250= -github.com/aws/aws-sdk-go-v2 v1.14.0/go.mod h1:ZA3Y8V0LrlWj63MQAnRHgKf/5QB//LSZCPNWlWrNGLU= +github.com/aws/aws-sdk-go v1.47.0 h1:/JUg9V1+xh+qBn8A6ec/l15ETPaMaBqxkjz+gg63dNk= github.com/aws/aws-sdk-go-v2 v1.16.16/go.mod h1:SwiyXi/1zTUZ6KIAmLK5V5ll8SiURNUYOqTerZPaF9k= -github.com/aws/aws-sdk-go-v2 v1.17.7/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= -github.com/aws/aws-sdk-go-v2 v1.18.1 h1:+tefE750oAb7ZQGzla6bLkOwfcQCEtC5y2RqoqCeqKo= -github.com/aws/aws-sdk-go-v2 v1.18.1/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.8 h1:tcFliCWne+zOuUfKNRn8JdFBuWPDuISDH08wD2ULkhk= +github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M= +github.com/aws/aws-sdk-go-v2 v1.21.2 h1:+LXZ0sgo8quN9UOKXXzAWRT3FWd4NxeXWOZom9pE7GA= +github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.8/go.mod h1:JTnlBSot91steJeti4ryyu/tLd4Sk84O5W22L7O2EQU= -github.com/aws/aws-sdk-go-v2/config v1.5.0/go.mod h1:RWlPOAW3E3tbtNAqTwvSW54Of/yP3oiZXMI0xfUdjyA= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 h1:OPLEkmhXf6xFPiz0bLeDArZIDx1NNS4oJyG4nv3Gct0= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13/go.mod h1:gpAbvyDGQFozTEmlTFO8XcQKHzubdq0LzRyJpG6MiXM= github.com/aws/aws-sdk-go-v2/config v1.17.7/go.mod h1:dN2gja/QXxFF15hQreyrqYhLBaQo1d9ZKe/v/uplQoI= -github.com/aws/aws-sdk-go-v2/config v1.18.27 h1:Az9uLwmssTE6OGTpsFqOnaGpLnKDqNYOJzWuC6UAYzA= -github.com/aws/aws-sdk-go-v2/config v1.18.27/go.mod h1:0My+YgmkGxeqjXZb5BYme5pc4drjTnM+x1GJ3zv42Nw= -github.com/aws/aws-sdk-go-v2/credentials v1.3.1/go.mod h1:r0n73xwsIVagq8RsxmZbGSRQFj9As3je72C2WzUIToc= +github.com/aws/aws-sdk-go-v2/config v1.19.1 h1:oe3vqcGftyk40icfLymhhhNysAwk0NfiwkDi2GTPMXs= +github.com/aws/aws-sdk-go-v2/config v1.19.1/go.mod h1:ZwDUgFnQgsazQTnWfeLWk5GjeqTQTL8lMkoE1UXzxdE= github.com/aws/aws-sdk-go-v2/credentials v1.12.20/go.mod h1:UKY5HyIux08bbNA7Blv4PcXQ8cTkGh7ghHMFklaviR4= -github.com/aws/aws-sdk-go-v2/credentials v1.13.26 h1:qmU+yhKmOCyujmuPY7tf5MxR/RKyZrOPO3V4DobiTUk= -github.com/aws/aws-sdk-go-v2/credentials v1.13.26/go.mod h1:GoXt2YC8jHUBbA4jr+W3JiemnIbkXOfxSXcisUsZ3os= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.3.0/go.mod h1:2LAuqPx1I6jNfaGDucWfA2zqQCYCOMCDHiCOciALyNw= +github.com/aws/aws-sdk-go-v2/credentials v1.13.43 h1:LU8vo40zBlo3R7bAvBVy/ku4nxGEyZe9N8MqAeFTzF8= +github.com/aws/aws-sdk-go-v2/credentials v1.13.43/go.mod h1:zWJBz1Yf1ZtX5NGax9ZdNjhhI4rgjfgsyk6vTY1yfVg= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.17/go.mod h1:yIkQcCDYNsZfXpd5UX2Cy+sWA1jPgIhGTw9cOBzfVnQ= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4 h1:LxK/bitrAr4lnh9LnIS6i7zWbCOdMsfzKFBI6LUCS0I= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4/go.mod h1:E1hLXN/BL2e6YizK1zFlYd8vsfi2GTjbjBazinMmeaM= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 h1:PIktER+hwIG286DqXyvVENjgLTAwGgoeriLDD5C+YlQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13/go.mod h1:f/Ib/qYjhV2/qdsf79H3QP/eRE4AkVyEf6sk7XfZ1tg= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.33 h1:fAoVmNGhir6BR+RU0/EI+6+D7abM+MCwWf8v4ip5jNI= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.33/go.mod h1:84XgODVR8uRhmOnUkKGUZKqIMxmjmLOR8Uyp7G/TPwc= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.5/go.mod h1:2hXc8ooJqF2nAznsbJQIn+7h851/bu8GVC80OVTTqf8= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23/go.mod h1:2DFxAQ9pfIRy0imBCJv+vZ2X6RKxves6fbnEuSry6b4= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.31/go.mod h1:QT0BqUvX1Bh2ABdTGnjqEjvjzrCfIniM9Sc8zn9Yndo= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34 h1:A5UqQEmPaCFpedKouS4v+dHCTUo2sKqhoKO9U5kxyWo= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34/go.mod h1:wZpTEecJe0Btj3IYnDx/VlUzor9wm3fJHyvLpQF0VwY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.3.0/go.mod h1:miRSv9l093jX/t/j+mBCaLqFHo9xKYzJ7DGm1BsGoJM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43 h1:nFBQlGtkbPzp/NjZLuFxRqmT91rLJkgvsEQs68h962Y= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17/go.mod h1:pRwaTYCJemADaqCbUAxltMoHKata7hmB5PjEXeu0kfg= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.25/go.mod h1:zBHOPwhBc3FlQjQJE/D3IfPWiWaQmT06Vq9aNukDo0k= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28 h1:srIVS45eQuewqz6fKKu6ZGXaq6FuFg5NzgQBAM6g8Y4= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28/go.mod h1:7VRpKQQedkfIEXb4k52I7swUnZP0wohVajJMRn3vsUw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.1.1/go.mod h1:Zy8smImhTdOETZqfyn01iNOe0CNggVbPjCajyaz6Gvg= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37 h1:JRVhO25+r3ar2mKGP7E0LDl8K9/G36gjlqca5iQbaqc= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24/go.mod h1:jULHjqqjDlbyTa7pfM7WICATnOv+iOhjletM3N0Xbu8= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35 h1:LWA+3kDM8ly001vJ1X1waCuLJdtTl48gwkPKWy9sosI= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35/go.mod h1:0Eg1YjxE0Bhn56lx+SHJwCzhW+2JGtizsrx+lCqrfm0= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14 h1:ZSIPAkAsCCjYrhqfw2+lNzWDzxzHXEckFkTePL5RSWQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45 h1:hze8YsjSh8Wl1rYa1CJpRmXP21BvOBuc76YhW0HsuQ4= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45/go.mod h1:lD5M20o09/LCuQ2mE62Mb/iSdSlCNuj6H5ci7tW7OsE= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14/go.mod h1:AyGgqiKv9ECM6IZeNQtdT8NnMvUb3/2wokeq2Fgryto= -github.com/aws/aws-sdk-go-v2/service/ecr v1.4.1/go.mod h1:FglZcyeiBqcbvyinl+n14aT/EWC7S1MIH+Gan2iizt0= -github.com/aws/aws-sdk-go-v2/service/ecr v1.18.7 h1:oQ1Esut3iaL2Dydt2RBd9gbuUevToXpdTI+Uh1xXryI= -github.com/aws/aws-sdk-go-v2/service/ecr v1.18.7/go.mod h1:RHhgOMnMIkgB4TmxQat9obSnZ6fF1fuA27+itZKUi1o= -github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.4.1/go.mod h1:eD5Eo4drVP2FLTw0G+SMIPWNWvQRGGTtIZR2XeAagoA= -github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.12.0 h1:LsqBpyRofMG6eDs6YGud6FhdGyIyXelAasPOZ6wWLro= -github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.12.0/go.mod h1:IArQ3IBR00FkuraKwudKZZU32OxJfdTdwV+W5iZh3Y4= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9 h1:Lh1AShsuIJTwMkoxVCAYPJgNG5H+eN6SmoUn8nOZ5wE= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4 h1:6lJvvkQ9HmbHZ4h/IEwclwv2mrTW8Uq1SOB/kXy0mfw= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4/go.mod h1:1PrKYwxTM+zjpw9Y41KFtoJCQrJ34Z47Y4VgVbfndjo= +github.com/aws/aws-sdk-go-v2/service/ecr v1.20.2 h1:y6LX9GUoEA3mO0qpFl1ZQHj1rFyPWVphlzebiSt2tKE= +github.com/aws/aws-sdk-go-v2/service/ecr v1.20.2/go.mod h1:Q0LcmaN/Qr8+4aSBrdrXXePqoX0eOuYpJLbYpilmWnA= +github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2 h1:PpbXaecV3sLAS6rjQiaKw4/jyq3Z8gNzmoJupHAoBp0= +github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2/go.mod h1:fUHpGXr4DrXkEDpGAjClPsviWf+Bszeb0daKE0blxv8= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9/go.mod h1:a9j48l6yL5XINLHLcOKInjdvknN+vWqPBxqeIDw7ktw= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.18 h1:BBYoNQt2kUZUUK4bIPsKrCcjVPUMNsgQpNAwhznK/zo= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14 h1:m0QTSI6pZYJTk5WSKx3fm5cNW/DCicVzULBgU/6IyD0= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14/go.mod h1:dDilntgHy9WnHXsh7dDtUPgHKEfTJIBUTHM8OWm0f/0= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.18/go.mod h1:NS55eQ4YixUJPTC+INxi2/jCqe1y2Uw3rnh9wEOVJxY= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.2.1/go.mod h1:zceowr5Z1Nh2WVP8bf/3ikB41IZW59E4yIYbg+pC6mw= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36 h1:eev2yZX7esGRjqRbnVk1UxMLw4CyVZDpZXRCcy75oQk= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36/go.mod h1:lGnOkH9NJATw0XEPcAknFBj3zzNTEGRHtSw+CwC1YTg= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.17/go.mod h1:4nYOrY41Lrbk2170/BGkcJKBhws9Pfn8MG3aGqjjeFI= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28 h1:bkRyG4a929RCnpVSTvLM2j/T4ls015ZhhYApbmYs15s= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28/go.mod h1:jj7znCIg05jXlaGBlFMGP8+7UN3VtCkRBG2spnmRQkU= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.17 h1:HfVVR1vItaG6le+Bpw6P4midjBDMKnjMyZnw9MXYUcE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37 h1:WWZA/I2K4ptBS1kg0kV1JbBtG/umed0vwHRrmcr9z7k= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37/go.mod h1:vBmDnwWXWxNPFRMmG2m/3MKOe+xEcMDo1tanpaWCcck= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.17/go.mod h1:YqMdV+gEKCQ59NrB7rzrJdALeBIsYiVi8Inj3+KcqHI= -github.com/aws/aws-sdk-go-v2/service/kms v1.22.2 h1:jwmtdM1/l1DRNy5jQrrYpsQm8zwetkgeqhAqefDr1yI= -github.com/aws/aws-sdk-go-v2/service/s3 v1.27.11 h1:3/gm/JTX9bX8CpzTgIlrtYpB3EVBDxyg/GY/QdcIEZw= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4 h1:v0jkRigbSD6uOdwcaUQmgEwG1BkPfAPDqaeNt/29ghg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4/go.mod h1:LhTyt8J04LL+9cIt7pYJ5lbS/U98ZmXovLOR/4LUsk8= +github.com/aws/aws-sdk-go-v2/service/kms v1.24.7 h1:uRGw0UKo5hc7M2T7uGsK/Yg2qwecq/dnVjQbbq9RCzY= github.com/aws/aws-sdk-go-v2/service/s3 v1.27.11/go.mod h1:fmgDANqTUCxciViKl9hb/zD5LFbvPINFRgWhDbR+vZo= -github.com/aws/aws-sdk-go-v2/service/sso v1.3.1/go.mod h1:J3A3RGUvuCZjvSuZEcOpHDnzZP/sKbhDWV2T1EOzFIM= +github.com/aws/aws-sdk-go-v2/service/s3 v1.40.0 h1:wl5dxN1NONhTDQD9uaEvNsDRX29cBmGED/nl0jkWlt4= +github.com/aws/aws-sdk-go-v2/service/s3 v1.40.0/go.mod h1:rDGMZA7f4pbmTtPOk5v5UM2lmX6UAbRnMDJeDvnH7AM= github.com/aws/aws-sdk-go-v2/service/sso v1.11.23/go.mod h1:/w0eg9IhFGjGyyncHIQrXtU8wvNsTJOP0R6PPj0wf80= -github.com/aws/aws-sdk-go-v2/service/sso v1.12.12 h1:nneMBM2p79PGWBQovYO/6Xnc2ryRMw3InnDJq1FHkSY= -github.com/aws/aws-sdk-go-v2/service/sso v1.12.12/go.mod h1:HuCOxYsF21eKrerARYO6HapNeh9GBNq7fius2AcwodY= +github.com/aws/aws-sdk-go-v2/service/sso v1.15.2 h1:JuPGc7IkOP4AaqcZSIcyqLpFSqBWK32rM9+a1g6u73k= +github.com/aws/aws-sdk-go-v2/service/sso v1.15.2/go.mod h1:gsL4keucRCgW+xA85ALBpRFfdSLH4kHOVSnLMSuBECo= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.5/go.mod h1:csZuQY65DAdFBt1oIjO5hhBR49kQqop4+lcuCjf2arA= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12 h1:2qTR7IFk7/0IN/adSFhYu9Xthr0zVFTgBrmPldILn80= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12/go.mod h1:E4VrHCPzmVB/KFXtqBGKb3c8zpbNBgKe3fisDNLAW5w= -github.com/aws/aws-sdk-go-v2/service/sts v1.6.0/go.mod h1:q7o0j7d7HrJk/vr9uUt3BVRASvcU7gYZB9PUgPiByXg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3 h1:HFiiRkf1SdaAmV3/BHOFZ9DjFynPHj8G/UIO1lQS+fk= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3/go.mod h1:a7bHA82fyUXOm+ZSWKU6PIoBxrjSprdLoM8xPYvzYVg= github.com/aws/aws-sdk-go-v2/service/sts v1.16.19/go.mod h1:h4J3oPZQbxLhzGnk+j9dfYHi5qIOVJ5kczZd658/ydM= -github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 h1:XFJ2Z6sNUUcAz9poj+245DMkrHE4h2j5I9/xD50RHfE= -github.com/aws/aws-sdk-go-v2/service/sts v1.19.2/go.mod h1:dp0yLPsLBOi++WTxzCjA/oZqi6NPIhoR+uF7GeMU9eg= -github.com/aws/smithy-go v1.6.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= -github.com/aws/smithy-go v1.11.0/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= +github.com/aws/aws-sdk-go-v2/service/sts v1.23.2 h1:0BkLfgeDjfZnZ+MhB3ONb01u9pwFYTCZVhlsSSBvlbU= +github.com/aws/aws-sdk-go-v2/service/sts v1.23.2/go.mod h1:Eows6e1uQEsc4ZaHANmsPRzAKcVDrcmjjWiih2+HUUQ= github.com/aws/smithy-go v1.13.3/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= -github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20220228164355-396b2034c795 h1:IWeCJzU+IYaO2rVEBlGPTBfe90cmGXFTLdhUFlzDGsY= -github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20220228164355-396b2034c795/go.mod h1:8vJsEZ4iRqG+Vx6pKhWK6U00qcj0KC37IsfszMkY6UE= +github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/smithy-go v1.15.0 h1:PS/durmlzvAFpQHDs4wi4sNNP9ExsqZh6IlfdHXgKK8= +github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8 h1:SoFYaT9UyGkR0+nogNyD/Lj+bsixB+SNuAS4ABlEs6M= +github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8/go.mod h1:2JF49jcDOrLStIXN/j/K1EKRq8a8R2qRnlZA6/o/c7c= github.com/b4b4r07/go-pipe v0.0.0-20191010045404-84b446f57366/go.mod h1:1ymsiQNa3qebVEEVtuIdhtAXRfjO4qFCFq1bBUOT2HE= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -340,9 +348,11 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembj github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= -github.com/buildkite/agent/v3 v3.49.0 h1:FSmRQz8YFhaCXg4MfE7JucPcY7mQ/HWM55ir1j3E9qM= -github.com/buildkite/agent/v3 v3.49.0/go.mod h1:iasSyh3KPjOPCnyvnZB1trkkX7jrdL8PnLBgjdVJxgU= -github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/buildkite/agent/v3 v3.58.0 h1:yyhsY47GZcuaKS5nlRo2jil4OSiNIP0GcNjqWD67y1Q= +github.com/buildkite/agent/v3 v3.58.0/go.mod h1:DfwabLiZUtIJII2WVc0jufwun74iOVidQG/R46E+z+w= +github.com/buildkite/interpolate v0.0.0-20200526001904-07f35b4ae251 h1:k6UDF1uPYOs0iy1HPeotNa155qXRWrzKnqAaGXHLZCE= +github.com/buildkite/interpolate v0.0.0-20200526001904-07f35b4ae251/go.mod h1:gbPR1gPu9dB96mucYIR7T3B7p/78hRVSOuzIWLHK2Y4= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTxfm6M= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= @@ -359,8 +369,8 @@ github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHe github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= -github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21 h1:XlpL9EHrPOBJMLDDOf35/G4t5rGAFNNAZQ3cDcWavtc= -github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21/go.mod h1:Zlre/PVxuSI9y6/UV4NwGixQ48RHQDSPiUkofr6rbMU= +github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 h1:krfRl01rzPzxSxyLyrChD+U+MzsBXbm0OwYYB67uF+4= +github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589/go.mod h1:OuDyvmLnMCwa2ep4Jkm6nyA0ocJuZlGyk2gGseVzERM= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -370,14 +380,15 @@ github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= -github.com/clbanning/mxj/v2 v2.5.6 h1:Jm4VaCI/+Ug5Q57IzEoZbwx4iQFA6wkXv72juUSeK+g= -github.com/clbanning/mxj/v2 v2.5.6/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= +github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= +github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME= +github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e85keuznYcH5rqI438v41pKcBl4ZxQ= github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= -github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= -github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.5 h1:g+wWynZqVALYAlpSQFAa7TscDnUK8mKYtrxMpw6AUKo= +github.com/cloudflare/circl v1.3.5/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudfoundry-incubator/candiedyaml v0.0.0-20170901234223-a41693b7b7af h1:6Cpkahw28+gcBdnXQL7LcMTX488+6jl6hfoTMRT6Hm4= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -515,8 +526,8 @@ github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmeka github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-oidc/v3 v3.6.0 h1:AKVxfYw1Gmkn/w96z0DbT/B/xFnzTd3MkZvWLjF4n/o= -github.com/coreos/go-oidc/v3 v3.6.0/go.mod h1:ZpHUsHBucTUj6WOkrP4E20UPynbLZzhTQ1XKCXkxyPc= +github.com/coreos/go-oidc/v3 v3.7.0 h1:FTdj0uexT4diYIPlF4yoFVI5MRO1r5+SEcIpEw9vC0o= +github.com/coreos/go-oidc/v3 v3.7.0/go.mod h1:yQzSCqBnK3e6Fs5l+f5i0F8Kwf0zpH9bPEsbY00KanM= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -530,13 +541,13 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7 h1:vU+EP9ZuFUCYE0NYLwTSob+3LNEJATzNfP/DC7SWGWI= -github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= +github.com/creack/pty v1.1.20 h1:VIPb/a2s17qNeQgDnkfZC35RScx+blkKF8GV68n80J4= +github.com/cyberphone/json-canonicalization v0.0.0-20231011164504-785e29786b46 h1:2Dx4IHfC1yHWI12AxQDJM1QbRCDfk6M+blLzlZCXdrc= +github.com/cyberphone/json-canonicalization v0.0.0-20231011164504-785e29786b46/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= @@ -546,43 +557,51 @@ github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg= +github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/depcheck-test/depcheck-test v0.0.0-20220607135614-199033aaa936 h1:foGzavPWwtoyBvjWyKJYDYsyzy+23iBV7NKTwdk+LRY= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/digitorus/pkcs7 v0.0.0-20221019075359-21b8b40e6bb4/go.mod h1:SKVExuS+vpu2l9IoOc0RwqE7NYnb0JlcFHFnEJkVDzc= -github.com/digitorus/pkcs7 v0.0.0-20221212123742-001c36b64ec3 h1:rjCXeRWazGsbcBlExMcAW8H1LGdgJ9r619y7+aeKgds= -github.com/digitorus/pkcs7 v0.0.0-20221212123742-001c36b64ec3/go.mod h1:SKVExuS+vpu2l9IoOc0RwqE7NYnb0JlcFHFnEJkVDzc= -github.com/digitorus/timestamp v0.0.0-20221019182153-ef3b63b79b31 h1:3go0tpsBpbs9L/oysk3jDwRprlLRRkpSU7YxKlTfU+o= -github.com/digitorus/timestamp v0.0.0-20221019182153-ef3b63b79b31/go.mod h1:6V2ND8Yf8TOJ4h+9pmUlx8kXvNLBB2QplToVVZQ3rF0= -github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/digitorus/pkcs7 v0.0.0-20230713084857-e76b763bdc49/go.mod h1:SKVExuS+vpu2l9IoOc0RwqE7NYnb0JlcFHFnEJkVDzc= +github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 h1:ge14PCmCvPjpMQMIAH7uKg0lrtNSOdpYsRXlwk3QbaE= +github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352/go.mod h1:SKVExuS+vpu2l9IoOc0RwqE7NYnb0JlcFHFnEJkVDzc= +github.com/digitorus/timestamp v0.0.0-20230902153158-687734543647 h1:WOk5Aclr/+sZ2/SX2YyxulNFwZOUhSrDJLw5KbHKmdE= +github.com/digitorus/timestamp v0.0.0-20230902153158-687734543647/go.mod h1:GvWntX9qiTlOud0WkQ6ewFm0LPy5JUR1Xo0Ngbd1w6Y= github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc= +github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v23.0.5+incompatible h1:ufWmAOuD3Vmr7JP2G5K3cyuNC4YZWiAsuDEvFVVDafE= -github.com/docker/cli v23.0.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v24.0.7+incompatible h1:wa/nIwYFW7BVTGa7SWPVyyXU9lgORqUb1xfI36MSkFg= +github.com/docker/cli v24.0.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= -github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= +github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.14+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v23.0.5+incompatible h1:DaxtlTJjFSnLOXVNUBU1+6kXGz2lpDoEAH6QoxaSg8k= -github.com/docker/docker v23.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= +github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c= -github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= -github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= +github.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8= +github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= @@ -605,12 +624,17 @@ github.com/drone/envsubst v1.0.3 h1:PCIBwNDYjs50AsLZPYdfhSATKaRg/FJmDc2D6+C2x8g= github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9bFiJ2g= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= +github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= +github.com/ebitengine/purego v0.5.0 h1:JrMGKfRIAM4/QVKaesIIT7m/UVjTj5GYhRSQYwfVdpo= +github.com/ebitengine/purego v0.5.0/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= -github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -630,13 +654,11 @@ github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJ github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4= github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= -github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw= -github.com/facebookgo/limitgroup v0.0.0-20150612190941-6abd8d71ec01 h1:IeaD1VDVBPlx3viJT9Md8if8IxxJnO+x0JCGb054heg= -github.com/facebookgo/muster v0.0.0-20150708232844-fd3d7953fd52 h1:a4DFiKFJiDRGFD1qIcqGLX/WlUMD9dyLSLDt+9QZgt8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= @@ -650,13 +672,13 @@ github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0X github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/fvbommel/sortorder v1.0.2 h1:mV4o8B2hKboCdkJm+a7uX/SIpZob4JzUpc5GGnM45eo= github.com/fvbommel/sortorder v1.0.2/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gardener/component-cli v0.44.0 h1:19w703QNyV0VRhoqbRv6NgibK/t6OZxoLqkBWO/JrFM= github.com/gardener/component-cli v0.44.0/go.mod h1:TMYFZYiopyvbgVzaMALgUcJvup3LP/qOl/NQpS7uvjM= github.com/gardener/component-spec/bindings-go v0.0.52/go.mod h1:kQFMTWowNAp9tOp6aImQa/NoLzfvX29jN5Qgud9rpQU= @@ -695,8 +717,9 @@ github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= @@ -708,14 +731,15 @@ github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9Qy github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= -github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= +github.com/go-openapi/errors v0.20.4 h1:unTcVm6PispJsMECE3zWgvG4xTiKda1LIR5rCRWLG6M= +github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= +github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= @@ -756,9 +780,9 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= -github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-rod/rod v0.113.3 h1:oLiKZW721CCMwA5g7977cWfcAKQ+FuosP47Zf1QiDrA= +github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= +github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-rod/rod v0.114.4 h1:FpkNFukjCuZLwnoLs+S9aCL95o/EMec6M+41UmvQay8= github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= @@ -800,12 +824,16 @@ github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXs github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godror/godror v0.24.2/go.mod h1:wZv/9vPiUib6tkoDl+AZ/QLf5YZgMravZ7jxH2eQWAE= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= @@ -821,6 +849,7 @@ github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -863,17 +892,19 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= +github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= -github.com/google/certificate-transparency-go v1.1.6 h1:SW5K3sr7ptST/pIvNkSVWMiJqemRmkjJPPT0jzXdOOY= -github.com/google/certificate-transparency-go v1.1.6/go.mod h1:0OJjOsOk+wj6aYQgP7FU0ioQ0AJUmnWPFMqTjQeazPQ= +github.com/google/certificate-transparency-go v1.1.7 h1:IASD+NtgSTJLPdzkthwvAG1ZVbF2WtFg4IvoA68XGSw= +github.com/google/certificate-transparency-go v1.1.7/go.mod h1:FSSBo8fyMVgqptbfF6j5p/XNdgQftAhSmXcIxV9iphE= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= +github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU= +github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49/go.mod h1:BkkQ4L1KS1xMt2aWSPStnn55ChGC0DPOn2FQYj+f25M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -888,15 +919,16 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= -github.com/google/go-containerregistry v0.15.2 h1:MMkSh+tjSdnmJZO7ljvEqV1DjfekB6VUEAZgy3a+TQE= -github.com/google/go-containerregistry v0.15.2/go.mod h1:wWK+LnOv4jXMM23IT/F1wdYftGWGr47Is8CG+pmHK1Q= +github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ= +github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FCD+K3FI= github.com/google/go-github/v45 v45.2.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28= -github.com/google/go-github/v50 v50.2.0 h1:j2FyongEHlO9nxXLc+LP3wuBSVU9mVxfpdYUexMpIfk= -github.com/google/go-github/v50 v50.2.0/go.mod h1:VBY8FB6yPIjrtKhozXv4FQupxKLS6H4m6xFZlT43q8Q= +github.com/google/go-github/v55 v55.0.0 h1:4pp/1tNMB9X/LuAhs5i0KQAE40NmiR/y6prLNb9x9cg= +github.com/google/go-github/v55 v55.0.0/go.mod h1:JLahOTA1DnXzhxEymmFF5PP2tSS9JVNj68mSZNDwskA= github.com/google/go-intervals v0.0.2/go.mod h1:MkaR3LNRfeKLPmqgJYs4E66z5InYjmCjbbr4TQlcT6Y= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= @@ -920,25 +952,27 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20221103000818-d260c55eee4c h1:lvddKcYTQ545ADhBujtIJmqQrZBDsGo7XIMbAQe/sNY= -github.com/google/pprof v0.0.0-20221103000818-d260c55eee4c/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= -github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/tink/go v1.7.0 h1:6Eox8zONGebBFcCBqkVmt60LaWZa6xg1cl/DwAh/J1w= +github.com/google/trillian v1.5.3 h1:3ioA5p09qz+U9/t2riklZtaQdZclaStp0/eQNfewNRg= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.4 h1:uGy6JWR/uMIILU8wbf+OkstIrNiMjGpEIyhx8f6W7s4= -github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4= +github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -956,6 +990,8 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= +github.com/gowebpki/jcs v1.0.1 h1:Qjzg8EOkrOTuWP7DqQ1FbYtcpEbeTzUoTN9bptp8FOU= +github.com/gowebpki/jcs v1.0.1/go.mod h1:CID1cNZ+sHp1CCpAR8mPf6QRtagFBgPJE0FCUQ6+BrI= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -978,37 +1014,37 @@ github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0= -github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA= +github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 h1:UpiO20jno/eV1eVZcxqWnUohyKRe1g8FPV/xH1s/2qs= github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= +github.com/hashicorp/go-sockaddr v1.0.5 h1:dvk7TIXCZpmfOlM+9mlcrWmWjw/wlKT+VDq2wMvfPJU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= +github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/vault/api v1.9.2 h1:YjkZLJ7K3inKgMZ0wzCU9OHqc+UqMQyXsPXnf3Cl2as= -github.com/honeycombio/beeline-go v1.10.0 h1:cUDe555oqvw8oD76BQJ8alk7FP0JZ/M/zXpNvOEDLDc= -github.com/honeycombio/libhoney-go v1.16.0 h1:kPpqoz6vbOzgp7jC6SR7SkNj7rua7rgxvznI6M3KdHc= +github.com/hashicorp/vault/api v1.10.0 h1:/US7sIjWN6Imp4o/Rj1Ce2Nr5bki/AXi9vAW3p2tOJQ= +github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef h1:A9HsByNhogrvm9cWb28sjiS3i7tcKCkflWFEkHfuAgM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= @@ -1023,8 +1059,8 @@ github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= -github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= -github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/in-toto/in-toto-golang v0.9.0 h1:tHny7ac4KgtsfrG6ybU8gVOZux2H8jN05AXJ9EBM1XU= github.com/in-toto/in-toto-golang v0.9.0/go.mod h1:xsBVrVsHNsB61++S6Dy2vWosKhuA3lUTQd+eF9HdeMo= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -1033,14 +1069,14 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ= github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw= -github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b h1:ZGiXF8sz7PDk6RgkP+A/SFfUD0ZR/AgG6SpRNEDKZy8= -github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b/go.mod h1:hQmNrgofl+IY/8L+n20H6E6PWBBTokdsv+q49j0QhsU= -github.com/jellydator/ttlcache/v3 v3.0.1 h1:cHgCSMS7TdQcoprXnWUptJZzyFsqs18Lt8VVhRuZYVU= +github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 h1:TMtDYDHKYY15rFihtRfck/bfFqNfvcabqvXAFQfAUpY= +github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= +github.com/jellydator/ttlcache/v3 v3.1.0 h1:0gPFG0IHHP6xyUyXq+JaD8fwkDCqgqwohXNJBcYE71g= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8 h1:CZkYfurY6KGhVtlalI4QwQ6T0Cu6iuY3e0x5RLu96WE= github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo= -github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d h1:jRQLvyVGL+iVtDElaEIDdKwpPqUIZJfzkNLV34htpEc= +github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -1048,7 +1084,7 @@ 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/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548 h1:dYTbLf4m0a5u0KLmPfB6mgxbcV7588bOCx79hxa5Sr4= +github.com/jmhodges/clock v1.2.0 h1:eq4kys+NI0PLngzaHEe7AmPT90XMGIEySD1JfV1PDIs= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= @@ -1087,10 +1123,11 @@ github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/klauspost/compress v1.15.2/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.15.7/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= -github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= +github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= +github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -1115,8 +1152,21 @@ github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhR github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/letsencrypt/boulder v0.0.0-20221109233200-85aa52084eaf h1:ndns1qx/5dL43g16EQkPV/i8+b3l5bYQwLeoSBe7tS8= -github.com/letsencrypt/boulder v0.0.0-20221109233200-85aa52084eaf/go.mod h1:aGkAgvWY/IUcVFfuly53REpfv5edu25oij+qHRFaraA= +github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= +github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= +github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= +github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= +github.com/lestrrat-go/httprc v1.0.4 h1:bAZymwoZQb+Oq8MEbyipag7iSq6YIga8Wj6GOiJGdI8= +github.com/lestrrat-go/httprc v1.0.4/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= +github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= +github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= +github.com/lestrrat-go/jwx/v2 v2.0.16 h1:TuH3dBkYTy2giQg/9D8f20znS3JtMRuQJ372boS3lWk= +github.com/lestrrat-go/jwx/v2 v2.0.16/go.mod h1:jBHyESp4e7QxfERM0UKkQ80/94paqNIEcdEfiUYz5zE= +github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= +github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/letsencrypt/boulder v0.0.0-20231026200631-000cd05d5491 h1:WGrKdjHtWC67RX96eTkYD2f53NDHhrq/7robWTAfk4s= +github.com/letsencrypt/boulder v0.0.0-20231026200631-000cd05d5491/go.mod h1:o158RFmdEbYyIZmXAbrvmJWesbyxlLKee6X64VPVuOc= github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= @@ -1128,7 +1178,6 @@ github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= @@ -1172,28 +1221,28 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= +github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= @@ -1275,6 +1324,8 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM= +github.com/oleiade/reflections v1.0.1/go.mod h1:rdFxbxq4QXVZWj0F+e9jqjDkc7dbp97vkRixKo2JR60= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -1324,8 +1375,8 @@ github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.3-0.20211202193544-a5463b7f9c84/go.mod h1:Qnt1q4cjDNQI9bT832ziho5Iw2BhK8o1KwLOwW56VP4= -github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8= -github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= +github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= @@ -1351,6 +1402,8 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc= +github.com/outcaste-io/ristretto v0.2.3 h1:AK4zt/fJ76kjlYObOeNwh4T3asEuaCmp26pOvUOL9w0= +github.com/outcaste-io/ristretto v0.2.3/go.mod h1:W8HywhmtlopSB1jeMg3JtdIhf+DYkLAr0VN/s4+MHac= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= @@ -1360,11 +1413,13 @@ github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrap github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= +github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= +github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1374,8 +1429,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/poy/onpar v0.0.0-20200406201722-06f95a1c68e8/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU= @@ -1391,15 +1446,15 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= -github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= +github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -1408,8 +1463,8 @@ github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+ github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -1422,12 +1477,15 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= +github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= +github.com/richardartoul/molecule v1.0.1-0.20221107223329-32cfee06a052 h1:Qp27Idfgi6ACvFQat5+VJvlYToylpM/hcyLBI3WaKPA= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= -github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -1449,8 +1507,13 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ= +github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sassoftware/relic v7.2.1+incompatible h1:Pwyh1F3I0r4clFJXkSI8bOyJINGqpgjJU3DYAZeI05A= github.com/sassoftware/relic v7.2.1+incompatible/go.mod h1:CWfAxv73/iLZ17rbyhIEq3K9hs5w6FpNMdUT//qR+zk= +github.com/sassoftware/relic/v7 v7.6.1 h1:O5s8ewCgq5QYNpv45dK4u6IpBmDM9RIcsbf/G1uXepQ= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= @@ -1459,8 +1522,10 @@ github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvK github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= -github.com/secure-systems-lab/go-securesystemslib v0.6.0 h1:T65atpAVCJQK14UA57LMdZGpHi4QYSH/9FZyNGqMYIA= -github.com/secure-systems-lab/go-securesystemslib v0.6.0/go.mod h1:8Mtpo9JKks/qhPG4HGZ2LGMvrPbzuxwfz/f/zLfEWkk= +github.com/secure-systems-lab/go-securesystemslib v0.7.0 h1:OwvJ5jQf9LnIAS83waAjPbcMsODrTQUpJ02eNLUoxBg= +github.com/secure-systems-lab/go-securesystemslib v0.7.0/go.mod h1:/2gYnlnHVQ6xeGtfIqFy7Do03K4cdCY0A/GlJLDKLHI= +github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= +github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -1472,20 +1537,20 @@ github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFR github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sigstore/cosign/v2 v2.1.1 h1:HOI6pWaEie0wLituDWWaqC5U9MaXablKNf6QroVhj6k= -github.com/sigstore/cosign/v2 v2.1.1/go.mod h1:S9KGmdQ/Dd29TdgUwGCNeXR7scJWZwREh4A9Za2PRPY= -github.com/sigstore/fulcio v1.3.1 h1:0ntW9VbQbt2JytoSs8BOGB84A65eeyvGSavWteYp29Y= -github.com/sigstore/fulcio v1.3.1/go.mod h1:/XfqazOec45ulJZpyL9sq+OsVQ8g2UOVoNVi7abFgqU= -github.com/sigstore/rekor v1.2.2-0.20230530122220-67cc9e58bd23 h1:eZY7mQFcc0VvNr0fiAK3/n7kh73+T06KzBEIUYzFSDQ= -github.com/sigstore/rekor v1.2.2-0.20230530122220-67cc9e58bd23/go.mod h1:h1tOLhldpfILtziWpUDgGBu0vulWk9Kh72t6XzBGJok= -github.com/sigstore/sigstore v1.7.1 h1:fCATemikcBK0cG4+NcM940MfoIgmioY1vC6E66hXxks= -github.com/sigstore/sigstore v1.7.1/go.mod h1:0PmMzfJP2Y9+lugD0wer4e7TihR5tM7NcIs3bQNk5xg= -github.com/sigstore/sigstore/pkg/signature/kms/aws v1.7.1 h1:rDHrG/63b3nBq3G9plg7iYnWN6lBhOfq/XultlCZgII= -github.com/sigstore/sigstore/pkg/signature/kms/azure v1.7.1 h1:X3ezwolP+b1jP3R6XPOWhUU0TZKONiv6EIRuySlZGrY= -github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.7.1 h1:mj1KhdzzP1me994bt1UXhq5KZGSR1SoqxTqcT+hfPMk= -github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.7.1 h1:fhOToGY5fC5TY101an8i/oDYpoLzUJ1nUFwhnHA1+XY= -github.com/sigstore/timestamp-authority v1.1.1 h1:EldrdeBED0edNzDMvYZDf5CyWgtSchtR9DKYyksNR8M= -github.com/sigstore/timestamp-authority v1.1.1/go.mod h1:cEDLEHl/L3ppqKDaiZ3Cg4ikcaYleuq90I/BFNePzF0= +github.com/sigstore/cosign/v2 v2.2.1 h1:HauwPOMYYaVdQsnvUbF0P+ZsVPrkTB0G7Eq65+z1bQc= +github.com/sigstore/cosign/v2 v2.2.1/go.mod h1:4l1hELKWoFYzZ/p7+umrK6dhdBoBW0JbQRCIjOZIM9g= +github.com/sigstore/fulcio v1.4.3 h1:9JcUCZjjVhRF9fmhVuz6i1RyhCc/EGCD7MOl+iqCJLQ= +github.com/sigstore/fulcio v1.4.3/go.mod h1:BQPWo7cfxmJwgaHlphUHUpFkp5+YxeJes82oo39m5og= +github.com/sigstore/rekor v1.3.3 h1:pLZ0UjutL7SUdeiysmJCabnRqvI7DsIxnJj8c/+e0Fk= +github.com/sigstore/rekor v1.3.3/go.mod h1:GO3udo2Xiu3/Uz4/U3vgjVq7w5Yq7eSpAFP1z7gE+yA= +github.com/sigstore/sigstore v1.7.5 h1:ij55dBhLwjICmLTBJZm7SqoQLdsu/oowDanACcJNs48= +github.com/sigstore/sigstore v1.7.5/go.mod h1:9OCmYWhzuq/G4e1cy9m297tuMRJ1LExyrXY3ZC3Zt/s= +github.com/sigstore/sigstore/pkg/signature/kms/aws v1.7.5 h1:ilufPp36exfpivctI3ElU4ZTckP3eVu6RxYebBb6u+M= +github.com/sigstore/sigstore/pkg/signature/kms/azure v1.7.5 h1:gLdNJJo+xMf7+IeFRlyA/Pjavndo9rivmf5ioYeuPmM= +github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.7.5 h1:Ku3MD55VXR7+uezCS4LOY0+y2EZFlGCGFyzl+ZSoPyo= +github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.7.5 h1:yWNBuL52Je3ukUGry1qwg00ujJF2UFWShzXFIAtmxZU= +github.com/sigstore/timestamp-authority v1.2.0 h1:Ffk10QsHxu6aLwySQ7WuaoWkD63QkmcKtozlEFot/VI= +github.com/sigstore/timestamp-authority v1.2.0/go.mod h1:ojKaftH78Ovfow9DzuNl5WgTCEYSa4m5622UkKDHRXc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -1507,13 +1572,15 @@ github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:s github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= +github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= @@ -1528,11 +1595,10 @@ github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHN github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -1544,10 +1610,9 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= -github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= -github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= +github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= +github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI= github.com/spiffe/go-spiffe/v2 v2.1.6 h1:4SdizuQieFyL9eNU+SPiCArH4kynzaKOOj0VvM8R7Xo= github.com/spiffe/go-spiffe/v2 v2.1.6/go.mod h1:eVDqm9xFvyqao6C+eQensb9ZPkyNEeaUbqbBpOhBnNk= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= @@ -1557,8 +1622,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0= github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -1571,11 +1636,11 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/sylabs/sif/v2 v2.7.0/go.mod h1:TiyBWsgWeh5yBeQFNuQnvROwswqK7YJT8JA1L53bsXQ= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -1586,16 +1651,18 @@ github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/thales-e-security/pool v0.0.2 h1:RAPs4q2EbWsTit6tpzuvTFlgFRJ3S8Evf5gtvVDbmPg= github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU= -github.com/theupdateframework/go-tuf v0.5.2 h1:habfDzTmpbzBLIFGWa2ZpVhYvFBoK0C1onC3a4zuPRA= -github.com/theupdateframework/go-tuf v0.5.2/go.mod h1:SyMV5kg5n4uEclsyxXJZI2UxPFJNDc4Y+r7wv+MlvTA= +github.com/theupdateframework/go-tuf v0.6.1 h1:6J89fGjQf7s0mLmTG7p7pO/MbKOg+bIXhaLyQdmbKuE= +github.com/theupdateframework/go-tuf v0.6.1/go.mod h1:LAFusuQsFNBnEyYoTuA5zZrF7iaQ4TEgBXm8lb6Vj18= github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c= github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0= +github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs= -github.com/tjfoc/gmsm v1.3.2 h1:7JVkAn5bvUJ7HtU08iW6UiD+UTmJTIToHCfeFzkcCxM= github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= +github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= +github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -1605,21 +1672,21 @@ github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG github.com/transparency-dev/merkle v0.0.2/go.mod h1:pqSy+OXefQ1EDUVmAJ8MUhHB9TXGuzVAT58PqBoHz1A= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= +github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= -github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= -github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= +github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts= +github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk= github.com/vbauerster/mpb/v7 v7.4.1/go.mod h1:Ygg2mV9Vj9sQBWqsK2m2pidcf9H3s6bNKtqd3/M4gBo= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= @@ -1629,17 +1696,17 @@ github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmF github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= -github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= -github.com/xanzy/go-gitlab v0.86.0 h1:jR8V9cK9jXRQDb46KOB20NCF3ksY09luaG0IfXE6p7w= -github.com/xanzy/go-gitlab v0.86.0/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw= +github.com/xanzy/go-gitlab v0.93.2 h1:kNNf3BYNYn/Zkig0B89fma12l36VLcYSGu7OnaRlRDg= +github.com/xanzy/go-gitlab v0.93.2/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -1672,6 +1739,7 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMzt github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= +github.com/zalando/go-keyring v0.2.2 h1:f0xmpYiSrHtSNAVgwip93Cg8tuF45HJM6rHq/A5RI/4= github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs= github.com/zeebo/errs v1.3.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -1689,8 +1757,8 @@ go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVd go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= -go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= -go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= +go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE= +go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -1707,49 +1775,57 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.2 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= -go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= -go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= -go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs= -go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= -go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= -go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= +go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ= go.starlark.net v0.0.0-20221028183056-acb66ad56dd2 h1:5/KzhcSqd4UgY51l17r7C5g/JiE6DRw1Vq7VJfQHuMc= go.starlark.net v0.0.0-20221028183056-acb66ad56dd2/go.mod h1:kIVgS18CjmEC3PqMd5kaJSGEifyV/CeB9x506ZJ1Vbk= -go.step.sm/crypto v0.32.1 h1:kAiL21zTqAgYu1geOYxH+ApUCUX+oclB25TccnNEYTU= -go.step.sm/crypto v0.32.1/go.mod h1:JwarCq+Sn6N8IbRSKfSJfjUNKfO8c4N1mcNxYXuxXzc= +go.step.sm/crypto v0.36.1 h1:hrHIc0qVcOowJB/r1SgPGu10d59onUw3czYeMLJluBc= +go.step.sm/crypto v0.36.1/go.mod h1:3b2wJhYMWzHpc8ke4CvTXOehx/FK5acd8rwXt+c8g68= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go4.org/intern v0.0.0-20211027215823-ae77deb06f29/go.mod h1:cS2ma+47FKrLPdXFpr7CuxiTW3eyJbWew4qx0qtQWDA= +go4.org/intern v0.0.0-20230525184215-6c62f75575cb h1:ae7kzL5Cfdmcecbh22ll7lYP3iuUdnfnhiPcSaDgH/8= +go4.org/intern v0.0.0-20230525184215-6c62f75575cb/go.mod h1:Ycrt6raEcnF5FTsLiLKkhBTO6DPX3RCUCUVnks3gFJU= +go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= +go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 h1:WJhcL4p+YeDxmZWg141nRm7XC8IDmhz7lk5GpadO1Sg= +go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1772,6 +1848,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= @@ -1779,13 +1856,14 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1798,8 +1876,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1827,9 +1905,10 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= -golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1871,6 +1950,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -1894,9 +1974,13 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1913,8 +1997,8 @@ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs= -golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw= +golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= +golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1929,8 +2013,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2006,7 +2090,6 @@ golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201005172224-997123666555/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2037,7 +2120,6 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2045,16 +2127,18 @@ golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -2064,9 +2148,12 @@ golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2081,9 +2168,12 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2170,14 +2260,17 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= -golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gomodules.xyz/jsonpatch/v2 v2.3.0 h1:8NFhfS6gzxNqjLIYnZxg319wZ5Qjnx4m/CcX+Klzazc= gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= @@ -2203,16 +2296,17 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= -google.golang.org/api v0.128.0 h1:RjPESny5CnQRn9V6siglged+DZCgfu9l6mO9dkX9VOg= -google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750= +google.golang.org/api v0.149.0 h1:b2CqT6kG+zqJIVKRQ3ELJVLN1PwHZ6DJ3dW8yl82rgY= +google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -2266,10 +2360,10 @@ google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEc google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao= -google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b h1:+YaDE2r2OG8t/z5qmsh7Y+XXwCbvadxxZ0YY6mTdrVA= +google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b h1:ZlWIi1wSK56/8hn4QcBp/j9M7Gt3U/3hZw3mC7vDICo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -2300,9 +2394,8 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= -google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -2316,11 +2409,13 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/DataDog/dd-trace-go.v1 v1.56.1 h1:AUe/ZF7xm6vYnigPe+TY54DmfWYJxhMRaw/TfvrbzvE= +gopkg.in/DataDog/dd-trace-go.v1 v1.56.1/go.mod h1:KDLJ3CWVOSuVVwu+0ZR5KZo2rP6c7YyBV3v387dIpUU= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/alexcesaro/statsd.v2 v2.0.0 h1:FXkZSCZIH17vLCO5sO2UucTHsH9pc+17F6pl3JVCwMc= gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII= gopkg.in/cenkalti/backoff.v2 v2.2.1/go.mod h1:S0QdOvT2AlerfSBkp0O+dk+bbIMaNbEmVk876gPCthU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -2334,6 +2429,8 @@ gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= +gopkg.in/go-jose/go-jose.v2 v2.6.1 h1:qEzJlIDmG9q5VO0M/o8tGS65QMHMS1w01TQJB1VPJ4U= +gopkg.in/go-jose/go-jose.v2 v2.6.1/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -2374,7 +2471,7 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= -gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= helm.sh/helm/v3 v3.12.2 h1:kFyDBr/mgJUlyGzVTCieG4wW0zmo7fcNRWK0+FKkxqU= helm.sh/helm/v3 v3.12.2/go.mod h1:v1PMayudIfZAvec3Wp4wAErensvK/rv5fu/xCiE6t3I= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2384,13 +2481,14 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a h1:1XCVEdxrvL6c0TGOhecLuB7U9zYNdxZEjvOqJreKZiM= +inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a/go.mod h1:e83i32mAQOW1LAqEIweALsuK2Uw4mhQadA5r7b0Wobo= k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs= -k8s.io/api v0.27.3 h1:yR6oQXXnUEBWEWcvPWS0jQL575KoAboQPfJAuKNrw5Y= -k8s.io/api v0.27.3/go.mod h1:C4BNvZnQOF7JA/0Xed2S+aUyJSfTGkGFxLXz9MnpIpg= +k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM= +k8s.io/api v0.28.3/go.mod h1:MRCV/jr1dW87/qJnZ57U5Pak65LGmQVkKTzf3AtKFHc= k8s.io/apiextensions-apiserver v0.27.2 h1:iwhyoeS4xj9Y7v8YExhUwbVuBhMr3Q4bd/laClBV6Bo= k8s.io/apiextensions-apiserver v0.27.2/go.mod h1:Oz9UdvGguL3ULgRdY9QMUzL2RZImotgxvGjdWRq6ZXQ= k8s.io/apimachinery v0.18.6/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= @@ -2400,8 +2498,8 @@ k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRp k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U= -k8s.io/apimachinery v0.27.3 h1:Ubye8oBufD04l9QnNtW05idcOe9Z3GQN8+7PqmuVcUM= -k8s.io/apimachinery v0.27.3/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= +k8s.io/apimachinery v0.28.3 h1:B1wYx8txOaCQG0HmYF6nbpU8dg6HvA06x5tEffvOe7A= +k8s.io/apimachinery v0.28.3/go.mod h1:uQTKmIqs+rAYaq+DFaoD2X7pcjLOqbQX2AOiO0nIpb8= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= @@ -2414,8 +2512,8 @@ k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y= -k8s.io/client-go v0.27.3 h1:7dnEGHZEJld3lYwxvLl7WoehK6lAq7GvgjxpA3nv1E8= -k8s.io/client-go v0.27.3/go.mod h1:2MBEKuTo6V1lbKy3z1euEGnhPfGZLKTS9tiJ2xodM48= +k8s.io/client-go v0.28.3 h1:2OqNb72ZuTZPKCl+4gTKvqao0AMOl9f3o2ijbAj3LI4= +k8s.io/client-go v0.28.3/go.mod h1:LTykbBp9gsA7SwqirlCXBWtK0guzfhpoW4qSm7i9dxo= k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= @@ -2435,8 +2533,8 @@ k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20201203183100-97869a43a9d9/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20220902162205-c0856e24416d h1:U9tB195lKdzwqicbJvyJeOXV7Klv+wNAWENRnXEGi08= -k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 h1:pWEwq4Asjm4vjW7vcsmijwBhOr1/shsbSYiWXmNGlks= +k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.2.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= @@ -2454,16 +2552,16 @@ k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= -k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= +k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= +k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= k8s.io/kubectl v0.27.2 h1:sSBM2j94MHBFRWfHIWtEXWCicViQzZsb177rNsKBhZg= k8s.io/kubectl v0.27.2/go.mod h1:GCOODtxPcrjh+EC611MqREkU8RjYBh10ldQCQ6zpFKw= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go v1.2.3 h1:v8PJl+gEAntI1pJ/LCrDgsuk+1PKVavVEPsYIHFE5uY= oras.land/oras-go v1.2.3/go.mod h1:M/uaPdYklze0Vf3AakfarnpoEckvw0ESbRdN8Z1vdJg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= @@ -2481,17 +2579,18 @@ sigs.k8s.io/kustomize/api v0.13.2 h1:kejWfLeJhUsTGioDoFNJET5LQe/ajzXhJGYoU+pJsiA sigs.k8s.io/kustomize/api v0.13.2/go.mod h1:DUp325VVMFVcQSq+ZxyDisA8wtldwHxLZbr1g94UHsw= sigs.k8s.io/kustomize/kyaml v0.14.1 h1:c8iibius7l24G2wVAGZn/Va2wNys03GXLjYVIcFVxKA= sigs.k8s.io/kustomize/kyaml v0.14.1/go.mod h1:AN1/IpawKilWD7V+YvQwRGUvuUOOWpjsHu6uHwonSF4= -sigs.k8s.io/release-utils v0.7.4 h1:17LmJrydpUloTCtaoWj95uKlcrUp4h2A9Sa+ZL+lV9w= -sigs.k8s.io/release-utils v0.7.4/go.mod h1:JEt2QPHItd5Pg2UKLAU8PEaSlF4bUjCZimpxFDgymVU= +sigs.k8s.io/release-utils v0.7.6 h1:mQxQRAIulbyz6y7eOCzklAelcpYjBj8MMGFcxNnyqto= +sigs.k8s.io/release-utils v0.7.6/go.mod h1:GZGWmbINwsLGKsoZKTeWUGp4F+Rbwhq4XDtJ45N+dLw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk= +sigs.k8s.io/structured-merge-diff/v4 v4.3.0/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +software.sslmate.com/src/go-pkcs12 v0.2.0 h1:nlFkj7bTysH6VkC4fGphtjXRbezREPgrHuJG20hBGPE= diff --git a/vendor/cloud.google.com/go/compute/internal/version.go b/vendor/cloud.google.com/go/compute/internal/version.go index 7513e24cc..5692fd4ad 100644 --- a/vendor/cloud.google.com/go/compute/internal/version.go +++ b/vendor/cloud.google.com/go/compute/internal/version.go @@ -15,4 +15,4 @@ package internal // Version is the current tagged release of the library. -const Version = "1.19.3" +const Version = "1.23.2" diff --git a/vendor/github.com/Azure/go-ansiterm/SECURITY.md b/vendor/github.com/Azure/go-ansiterm/SECURITY.md new file mode 100644 index 000000000..e138ec5d6 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/SECURITY.md @@ -0,0 +1,41 @@ + + +## Security + +Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). + +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). + +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). + + diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go b/vendor/github.com/Azure/go-autorest/autorest/adal/token.go index c90209a94..2a24ab80c 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/token.go @@ -127,6 +127,9 @@ type TokenRefreshCallback func(Token) error // TokenRefresh is a type representing a custom callback to refresh a token type TokenRefresh func(ctx context.Context, resource string) (*Token, error) +// JWTCallback is the type representing callback that will be called to get the federated OIDC JWT +type JWTCallback func() (string, error) + // Token encapsulates the access token used to authorize Azure requests. // https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow#service-to-service-access-token-response type Token struct { @@ -367,14 +370,18 @@ func (secret ServicePrincipalAuthorizationCodeSecret) MarshalJSON() ([]byte, err // ServicePrincipalFederatedSecret implements ServicePrincipalSecret for Federated JWTs. type ServicePrincipalFederatedSecret struct { - jwt string + jwtCallback JWTCallback } // SetAuthenticationValues is a method of the interface ServicePrincipalSecret. // It will populate the form submitted during OAuth Token Acquisition using a JWT signed by an OIDC issuer. -func (secret *ServicePrincipalFederatedSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { +func (secret *ServicePrincipalFederatedSecret) SetAuthenticationValues(_ *ServicePrincipalToken, v *url.Values) error { + jwt, err := secret.jwtCallback() + if err != nil { + return err + } - v.Set("client_assertion", secret.jwt) + v.Set("client_assertion", jwt) v.Set("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") return nil } @@ -687,6 +694,8 @@ func NewServicePrincipalTokenFromAuthorizationCode(oauthConfig OAuthConfig, clie } // NewServicePrincipalTokenFromFederatedToken creates a ServicePrincipalToken from the supplied federated OIDC JWT. +// +// Deprecated: Use NewServicePrincipalTokenFromFederatedTokenWithCallback to refresh jwt dynamically. func NewServicePrincipalTokenFromFederatedToken(oauthConfig OAuthConfig, clientID string, jwt string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { if err := validateOAuthConfig(oauthConfig); err != nil { return nil, err @@ -700,12 +709,37 @@ func NewServicePrincipalTokenFromFederatedToken(oauthConfig OAuthConfig, clientI if jwt == "" { return nil, fmt.Errorf("parameter 'jwt' cannot be empty") } + return NewServicePrincipalTokenFromFederatedTokenCallback( + oauthConfig, + clientID, + func() (string, error) { + return jwt, nil + }, + resource, + callbacks..., + ) +} + +// NewServicePrincipalTokenFromFederatedTokenCallback creates a ServicePrincipalToken from the supplied federated OIDC JWTCallback. +func NewServicePrincipalTokenFromFederatedTokenCallback(oauthConfig OAuthConfig, clientID string, jwtCallback JWTCallback, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err + } + if err := validateStringParam(clientID, "clientID"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + if jwtCallback == nil { + return nil, fmt.Errorf("parameter 'jwtCallback' cannot be empty") + } return NewServicePrincipalTokenWithSecret( oauthConfig, clientID, resource, &ServicePrincipalFederatedSecret{ - jwt: jwt, + jwtCallback: jwtCallback, }, callbacks..., ) diff --git a/vendor/github.com/DataDog/appsec-internal-go/LICENSE b/vendor/github.com/DataDog/appsec-internal-go/LICENSE new file mode 100644 index 000000000..9301dd7ab --- /dev/null +++ b/vendor/github.com/DataDog/appsec-internal-go/LICENSE @@ -0,0 +1,200 @@ + 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 2016-present Datadog, Inc. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/DataDog/appsec-internal-go/httpsec/client_ip.go b/vendor/github.com/DataDog/appsec-internal-go/httpsec/client_ip.go new file mode 100644 index 000000000..3761a7739 --- /dev/null +++ b/vendor/github.com/DataDog/appsec-internal-go/httpsec/client_ip.go @@ -0,0 +1,126 @@ +package httpsec + +import ( + "net" + "net/textproto" + "strings" + + "github.com/DataDog/appsec-internal-go/netip" +) + +const ( + // RemoteIPTag is the tag name used for the remote HTTP request IP address. + RemoteIPTag = "network.client.ip" + // ClientIPTag is the tag name used for the client IP deduced from the HTTP + // request headers with ClientIP(). + ClientIPTag = "http.client_ip" +) + +// ClientIPTags returns the resulting Datadog span tags `http.client_ip` +// containing the client IP and `network.client.ip` containing the remote IP. +// The tags are present only if a valid ip address has been returned by +// ClientIP(). +func ClientIPTags(remoteIP, clientIP netip.Addr) (tags map[string]string) { + remoteIPValid := remoteIP.IsValid() + clientIPValid := clientIP.IsValid() + if !remoteIPValid && !clientIPValid { + return nil + } + + tags = make(map[string]string, 2) + if remoteIPValid { + tags[RemoteIPTag] = remoteIP.String() + } + if clientIPValid { + tags[ClientIPTag] = clientIP.String() + } + return tags +} + +// ClientIP returns the first public IP address found in the given headers. If +// none is present, it returns the first valid IP address present, possibly +// being a local IP address. The remote address, when valid, is used as fallback +// when no IP address has been found at all. +func ClientIP(hdrs map[string][]string, hasCanonicalHeaders bool, remoteAddr string, monitoredHeaders []string) (remoteIP, clientIP netip.Addr) { + // Walk IP-related headers + var foundIP netip.Addr +headersLoop: + for _, headerName := range monitoredHeaders { + if hasCanonicalHeaders { + headerName = textproto.CanonicalMIMEHeaderKey(headerName) + } + + headerValues, exists := hdrs[headerName] + if !exists { + continue // this monitored header is not present + } + + // Assuming a list of comma-separated IP addresses, split them and build + // the list of values to try to parse as IP addresses + var ips []string + for _, ip := range headerValues { + ips = append(ips, strings.Split(ip, ",")...) + } + + // Look for the first valid or global IP address in the comma-separated list + for _, ipstr := range ips { + ip := parseIP(strings.TrimSpace(ipstr)) + if !ip.IsValid() { + continue + } + // Replace foundIP if still not valid in order to keep the oldest + if !foundIP.IsValid() { + foundIP = ip + } + if isGlobal(ip) { + foundIP = ip + break headersLoop + } + } + } + + // Decide which IP address is the client one by starting with the remote IP + if ip := parseIP(remoteAddr); ip.IsValid() { + remoteIP = ip + clientIP = ip + } + + // The IP address found in the headers supersedes a private remote IP address. + if foundIP.IsValid() && !isGlobal(remoteIP) || isGlobal(foundIP) { + clientIP = foundIP + } + + return remoteIP, clientIP +} + +func parseIP(s string) netip.Addr { + if ip, err := netip.ParseAddr(s); err == nil { + return ip + } + if h, _, err := net.SplitHostPort(s); err == nil { + if ip, err := netip.ParseAddr(h); err == nil { + return ip + } + } + return netip.Addr{} +} + +var ipv6SpecialNetworks = [...]netip.Prefix{ + netip.MustParsePrefix("fec0::/10"), // site local +} + +func isGlobal(ip netip.Addr) bool { + // IsPrivate also checks for ipv6 ULA. + // We care to check for these addresses are not considered public, hence not global. + // See https://www.rfc-editor.org/rfc/rfc4193.txt for more details. + isGlobal := ip.IsValid() && !ip.IsPrivate() && !ip.IsLoopback() && !ip.IsLinkLocalUnicast() + if !isGlobal || !ip.Is6() { + return isGlobal + } + for _, n := range ipv6SpecialNetworks { + if n.Contains(ip) { + return false + } + } + return isGlobal +} diff --git a/vendor/github.com/DataDog/appsec-internal-go/netip/ip_default.go b/vendor/github.com/DataDog/appsec-internal-go/netip/ip_default.go new file mode 100644 index 000000000..f2906a0cb --- /dev/null +++ b/vendor/github.com/DataDog/appsec-internal-go/netip/ip_default.go @@ -0,0 +1,32 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2022 Datadog, Inc. + +//go:build !go1.19 +// +build !go1.19 + +package netip + +import "inet.af/netaddr" + +// Addr wraps an netaddr.IP value +type Addr = netaddr.IP + +// Prefix wraps an netaddr.IPPrefix value +type Prefix = netaddr.IPPrefix + +var ( + // ParseAddr wraps the netaddr.ParseIP function + ParseAddr = netaddr.ParseIP + // ParsePrefix wraps the netaddr.ParseIPPrefix function + ParsePrefix = netaddr.ParseIPPrefix + // MustParsePrefix wraps the netaddr.MustParseIPPrefix function + MustParsePrefix = netaddr.MustParseIPPrefix + // MustParseAddr wraps the netaddr.MustParseIP function + MustParseAddr = netaddr.MustParseIP + // IPv4 wraps the netaddr.IPv4 function + IPv4 = netaddr.IPv4 + // AddrFrom16 wraps the netaddr.IPv6Raw function + AddrFrom16 = netaddr.IPv6Raw +) diff --git a/vendor/github.com/DataDog/appsec-internal-go/netip/ip_go119.go b/vendor/github.com/DataDog/appsec-internal-go/netip/ip_go119.go new file mode 100644 index 000000000..2c185de6f --- /dev/null +++ b/vendor/github.com/DataDog/appsec-internal-go/netip/ip_go119.go @@ -0,0 +1,34 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2022 Datadog, Inc. + +//go:build go1.19 +// +build go1.19 + +package netip + +import "net/netip" + +// Addr wraps a netip.Addr value +type Addr = netip.Addr + +// Prefix wraps a netip.Prefix value +type Prefix = netip.Prefix + +var ( + // ParseAddr wraps the netip.ParseAddr function + ParseAddr = netip.ParseAddr + // MustParsePrefix wraps the netip.MustParsePrefix function + MustParsePrefix = netip.MustParsePrefix + // MustParseAddr wraps the netip.MustParseAddr function + MustParseAddr = netip.MustParseAddr + // AddrFrom16 wraps the netIP.AddrFrom16 function + AddrFrom16 = netip.AddrFrom16 +) + +// IPv4 wraps the netip.AddrFrom4 function +func IPv4(a, b, c, d byte) Addr { + e := [4]byte{a, b, c, d} + return netip.AddrFrom4(e) +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/LICENSE b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/LICENSE new file mode 100644 index 000000000..b370545be --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/LICENSE @@ -0,0 +1,200 @@ + 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 2016-present Datadog, Inc. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/cache.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/cache.go new file mode 100644 index 000000000..3993390d2 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/cache.go @@ -0,0 +1,90 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package obfuscate + +import ( + "fmt" + "time" + + "github.com/outcaste-io/ristretto" +) + +// measuredCache is a wrapper on top of *ristretto.Cache which additionally +// sends metrics (hits and misses) every 10 seconds. +type measuredCache struct { + *ristretto.Cache + + // close allows sending shutdown notification. + close chan struct{} + statsd StatsClient +} + +// Close gracefully closes the cache when active. +func (c *measuredCache) Close() { + if c.Cache == nil { + return + } + c.close <- struct{}{} + <-c.close +} + +func (c *measuredCache) statsLoop() { + defer func() { + c.close <- struct{}{} + }() + tick := time.NewTicker(10 * time.Second) + defer tick.Stop() + mx := c.Cache.Metrics + for { + select { + case <-tick.C: + c.statsd.Gauge("datadog.trace_agent.ofuscation.sql_cache.hits", float64(mx.Hits()), nil, 1) //nolint:errcheck + c.statsd.Gauge("datadog.trace_agent.ofuscation.sql_cache.misses", float64(mx.Misses()), nil, 1) //nolint:errcheck + case <-c.close: + c.Cache.Close() + return + } + } +} + +type cacheOptions struct { + On bool + Statsd StatsClient +} + +// newMeasuredCache returns a new measuredCache. +func newMeasuredCache(opts cacheOptions) *measuredCache { + if !opts.On { + // a nil *ristretto.Cache is a no-op cache + return &measuredCache{} + } + cfg := &ristretto.Config{ + // We know that the maximum allowed resource length is 5K. This means that + // in 5MB we can store a minimum of 1000 queries. + MaxCost: 5000000, + + // An appromixated worst-case scenario when the cache is filled with small + // queries averaged as being of length 11 ("LOCK TABLES"), we would be able + // to fit 476K of them into 5MB of cost. + // + // We average it to 500K and multiply 10x as the documentation recommends. + NumCounters: 500000 * 10, + + BufferItems: 64, // default recommended value + Metrics: true, // enable hit/miss counters + } + cache, err := ristretto.NewCache(cfg) + if err != nil { + panic(fmt.Errorf("Error starting obfuscator query cache: %v", err)) + } + c := measuredCache{ + close: make(chan struct{}), + statsd: opts.Statsd, + Cache: cache, + } + go c.statsLoop() + return &c +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/credit_cards.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/credit_cards.go new file mode 100644 index 000000000..03adf1544 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/credit_cards.go @@ -0,0 +1,211 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package obfuscate + +// IsCardNumber checks if b could be a credit card number by checking the digit count and IIN prefix. +// If validateLuhn is true, the Luhn checksum is also applied to potential candidates. +func IsCardNumber(b string, validateLuhn bool) (ok bool) { + // + // Just credit card numbers for now, based on: + // • https://baymard.com/checkout-usability/credit-card-patterns + // • https://www.regular-expressions.info/creditcard.html + // + if len(b) == 0 { + return false + } + if len(b) < 12 { + // fast path: can not be a credit card + return false + } + if b[0] != ' ' && b[0] != '-' && (b[0] < '0' || b[0] > '9') { + // fast path: only valid characters are 0-9, space (" ") and dash("-") + return false + } + prefix := 0 // holds up to b[:6] digits as a numeric value (for example []byte{"523"} becomes int(523)) for checking prefixes + count := 0 // counts digits encountered + foundPrefix := false // reports whether we've detected a valid prefix + recdigit := func(_ byte) {} // callback on each found digit; no-op by default (we only need this for Luhn) + if validateLuhn { + // we need Luhn checksum validation, so we have to take additional action + // and record all digits found + buf := make([]byte, 0, len(b)) + recdigit = func(b byte) { buf = append(buf, b) } + defer func() { + if !ok { + // if isCardNumber returned false, it means that b can not be + // a credit card number + return + } + // potentially a credit card number, run the Luhn checksum + ok = luhnValid(buf) + }() + } +loop: + for i := range b { + // We traverse and search b for a valid IIN credit card prefix based + // on the digits found, ignoring spaces and dashes. + // Source: https://www.regular-expressions.info/creditcard.html + switch b[i] { + case ' ', '-': + // ignore space (' ') and dash ('-') + continue loop + } + if b[i] < '0' || b[i] > '9' { + // not a 0 to 9 digit; can not be a credit card number; abort + return false + } + count++ + recdigit(b[i]) + if !foundPrefix { + // we have not yet found a valid prefix so we convert the digits + // that we have so far into a numeric value: + prefix = prefix*10 + (int(b[i]) - '0') + maybe, yes := validCardPrefix(prefix) + if yes { + // we've found a valid prefix; continue counting + foundPrefix = true + } else if !maybe { + // this is not a valid prefix and we should not continue looking + return false + } + } + if count > 16 { + // too many digits + return false + } + } + if count < 12 { + // too few digits + return false + } + return foundPrefix +} + +// luhnValid checks that the number represented in the given string validates the Luhn Checksum algorithm. +// str is expected to contain exclusively digits at all positions. +// +// See: +// • https://en.wikipedia.org/wiki/Luhn_algorithm +// • https://dev.to/shiraazm/goluhn-a-simple-library-for-generating-calculating-and-verifying-luhn-numbers-588j +func luhnValid(str []byte) bool { + var ( + sum int + alt bool + ) + n := len(str) + for i := n - 1; i > -1; i-- { + if str[i] < '0' || str[i] > '9' { + return false // not a number! + } + mod := int(str[i] - 0x30) // convert byte to int + if alt { + mod *= 2 + if mod > 9 { + mod = (mod % 10) + 1 + } + } + alt = !alt + sum += mod + } + return sum%10 == 0 +} + +// validCardPrefix validates whether b is a valid card prefix. Maybe returns true if +// the prefix could be an IIN once more digits are revealed and yes reports whether +// b is a fully valid IIN. +// +// If yes is false and maybe is false, there is no reason to continue searching. The +// prefix is invalid. +// +// IMPORTANT: If adding new prefixes to this algorithm, make sure that you update +// the "maybe" clauses above, in the shorter prefixes than the one you are adding. +// This refers to the cases which return true, false. +// +// TODO(x): this whole code could be code generated from a prettier data structure. +// Ultimately, it could even be user-configurable. +func validCardPrefix(n int) (maybe, yes bool) { + // Validates IIN prefix possibilities + // Source: https://www.regular-expressions.info/creditcard.html + if n > 699999 { + // too long for any known prefix; stop looking + return false, false + } + if n < 10 { + switch n { + case 1, 4: + // 1 & 4 are valid IIN + return false, true + case 2, 3, 5, 6: + // 2, 3, 5, 6 could be the start of valid IIN + return true, false + default: + // invalid IIN + return false, false + } + } + if n < 100 { + if (n >= 34 && n <= 39) || + (n >= 51 && n <= 55) || + n == 62 || + n == 65 { + // 34-39, 51-55, 62, 65 are valid IIN + return false, true + } + if n == 30 || n == 63 || n == 64 || n == 50 || n == 60 || + (n >= 22 && n <= 27) || (n >= 56 && n <= 58) || (n >= 60 && n <= 69) { + // 30, 63, 64, 50, 60, 22-27, 56-58, 60-69 may end up as valid IIN + return true, false + } + } + if n < 1000 { + if (n >= 300 && n <= 305) || + (n >= 644 && n <= 649) || + n == 309 || + n == 636 { + // 300‑305, 309, 636, 644‑649 are valid IIN + return false, true + } + if (n >= 352 && n <= 358) || n == 501 || n == 601 || + (n >= 222 && n <= 272) || (n >= 500 && n <= 509) || + (n >= 560 && n <= 589) || (n >= 600 && n <= 699) { + // 352-358, 501, 601, 222-272, 500-509, 560-589, 600-699 may be a 4 or 6 digit IIN prefix + return true, false + } + } + if n < 10000 { + if (n >= 3528 && n <= 3589) || + n == 5019 || + n == 6011 { + // 3528‑3589, 5019, 6011 are valid IINs + return false, true + } + if (n >= 2221 && n <= 2720) || (n >= 5000 && n <= 5099) || + (n >= 5600 && n <= 5899) || (n >= 6000 && n <= 6999) { + // maybe a 6-digit IIN + return true, false + } + } + if n < 100000 { + if (n >= 22210 && n <= 27209) || + (n >= 50000 && n <= 50999) || + (n >= 56000 && n <= 58999) || + (n >= 60000 && n <= 69999) { + // maybe a 6-digit IIN + return true, false + } + } + if n < 1000000 { + if (n >= 222100 && n <= 272099) || + (n >= 500000 && n <= 509999) || + (n >= 560000 && n <= 589999) || + (n >= 600000 && n <= 699999) { + // 222100‑272099, 500000‑509999, 560000‑589999, 600000‑699999 are valid IIN + return false, true + } + } + // unknown IIN + return false, false +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/http.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/http.go new file mode 100644 index 000000000..d9a00084f --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/http.go @@ -0,0 +1,60 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package obfuscate + +import ( + "net/url" + "strings" +) + +// obfuscateUserInfo returns a URL string that obfuscates any userinfo by setting url.User to nil. +func obfuscateUserInfo(val string) string { + u, err := url.Parse(val) + if err != nil { + return val + } + u.User = nil + return u.String() +} + +// ObfuscateURLString obfuscates the given URL. It must be a valid URL. +func (o *Obfuscator) ObfuscateURLString(val string) string { + if !o.opts.HTTP.RemoveQueryString && !o.opts.HTTP.RemovePathDigits { + // nothing to do + return obfuscateUserInfo(val) + } + u, err := url.Parse(val) + if err != nil { + // should not happen for valid URLs, but better obfuscate everything + // rather than expose sensitive information when this option is on. + return "?" + } + u.User = nil + if o.opts.HTTP.RemoveQueryString && u.RawQuery != "" { + u.ForceQuery = true // add the '?' + u.RawQuery = "" + } + if o.opts.HTTP.RemovePathDigits { + segs := strings.Split(u.Path, "/") + var changed bool + for i, seg := range segs { + for _, ch := range []byte(seg) { + if ch >= '0' && ch <= '9' { + // we can not set the question mark directly here because the url + // package will escape it into %3F, so we use this placeholder and + // replace it further down. + segs[i] = "/REDACTED/" + changed = true + break + } + } + } + if changed { + u.Path = strings.Join(segs, "/") + } + } + return strings.Replace(u.String(), "/REDACTED/", "?", -1) +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json.go new file mode 100644 index 000000000..8252a9f0f --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json.go @@ -0,0 +1,229 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package obfuscate + +import ( + "bytes" + "strconv" + "strings" + "sync" +) + +// ObfuscateMongoDBString obfuscates the given MongoDB JSON query. +func (o *Obfuscator) ObfuscateMongoDBString(cmd string) string { + return obfuscateJSONString(cmd, o.mongo) +} + +// ObfuscateElasticSearchString obfuscates the given ElasticSearch JSON query. +func (o *Obfuscator) ObfuscateElasticSearchString(cmd string) string { + return obfuscateJSONString(cmd, o.es) +} + +// obfuscateJSONString obfuscates the given span's tag using the given obfuscator. If the obfuscator is +// nil it is considered disabled. +func obfuscateJSONString(cmd string, obfuscator *jsonObfuscator) string { + if obfuscator == nil || cmd == "" { + // obfuscator is disabled or string is empty + return cmd + } + out, _ := obfuscator.obfuscate([]byte(cmd)) + // we should accept whatever the obfuscator returns, even if it's an error: a parsing + // error simply means that the JSON was invalid, meaning that we've only obfuscated + // as much of it as we could. It is safe to accept the output, even if partial. + return out +} + +type jsonObfuscator struct { + buffPool sync.Pool // pool for fixed-length buffers (50 showed to be the optimal running benchmarks with different length) + statePool sync.Pool // pool for jsonObfuscatorState values + keepKeys map[string]bool // the values for these keys will not be obfuscated + transformKeys map[string]bool // the values for these keys pass through the transformer + transformer func(string) string +} + +func newJSONObfuscator(cfg *JSONConfig, o *Obfuscator) *jsonObfuscator { + keepValue := make(map[string]bool, len(cfg.KeepValues)) + for _, v := range cfg.KeepValues { + keepValue[v] = true + } + var ( + transformKeys map[string]bool + transformer func(string) string + ) + if len(cfg.ObfuscateSQLValues) > 0 { + transformer = sqlObfuscationTransformer(o) + transformKeys = make(map[string]bool, len(cfg.ObfuscateSQLValues)) + for _, v := range cfg.ObfuscateSQLValues { + transformKeys[v] = true + } + } + return &jsonObfuscator{ + keepKeys: keepValue, + transformKeys: transformKeys, + transformer: transformer, + buffPool: sync.Pool{ + New: func() any { + return new(bytes.Buffer) + }, + }, + statePool: sync.Pool{ + New: func() any { + return &jsonObfuscatorState{ + closures: []bool{}, + } + }, + }, + } +} + +func sqlObfuscationTransformer(o *Obfuscator) func(string) string { + return func(s string) string { + result, err := o.ObfuscateSQLString(s) + if err != nil { + o.log.Debugf("Failed to obfuscate SQL string '%s': %s", s, err.Error()) + // instead of returning an empty string we explicitly return an error string here within the result in order + // to surface the problem clearly to the user + return "Datadog-agent failed to obfuscate SQL string. Enable agent debug logs for more info." + } + return result.Query + } +} + +type jsonObfuscatorState struct { + scan scanner // scanner + closures []bool // closure stack, true if object (e.g. {[{ => []bool{true, false, true}) + keepDepth int // the depth at which we've stopped obfuscating + key bool // true if scanning a key + wiped bool // true if obfuscation string (`"?"`) was already written for current value + keeping bool // true if not obfuscating + transformingValue bool // true if collecting the next literal for transformation +} + +func (st *jsonObfuscatorState) reset() { + st.scan.reset() + st.closures = st.closures[0:0] + st.keepDepth = 0 + st.key = false + st.wiped = false + st.keeping = false + st.transformingValue = false +} + +// setKey verifies if we are currently scanning a key based on the current state +// and updates the state accordingly. It must be called only after a closure or a +// value scan has ended. +func (st *jsonObfuscatorState) setKey() { + n := len(st.closures) + st.key = n == 0 || st.closures[n-1] // true if we are at top level or in an object + st.wiped = false +} + +func (p *jsonObfuscator) obfuscate(data []byte) (string, error) { + if len(data) == 0 { + return "", nil + } + + var out strings.Builder + st := p.statePool.Get().(*jsonObfuscatorState) + st.reset() + + buf := p.buffPool.Get().(*bytes.Buffer) // recording current token + buf.Reset() + defer func() { + p.statePool.Put(st) + p.buffPool.Put(buf) + }() + + out.Grow(len(data)) + buf.Grow(len(data) / 10) // Benchmarks show that the optimal point is a tenth of the data length. + for _, c := range data { + st.scan.bytes++ + op := st.scan.step(&st.scan, c) + depth := len(st.closures) + switch op { + case scanBeginObject: + // object begins: { + st.closures = append(st.closures, true) + st.setKey() + st.transformingValue = false + case scanBeginArray: + // array begins: [ + st.closures = append(st.closures, false) + st.setKey() + st.transformingValue = false + case scanEndArray, scanEndObject: + // array or object closing + if n := len(st.closures) - 1; n > 0 { + st.closures = st.closures[:n] + } + fallthrough + case scanObjectValue, scanArrayValue: + // done scanning value + st.setKey() + if st.transformingValue && p.transformer != nil { + v, err := strconv.Unquote(buf.String()) + if err != nil { + v = buf.String() + } + result := p.transformer(v) + out.WriteByte('"') + out.WriteString(result) + out.WriteByte('"') + st.transformingValue = false + buf.Reset() + } else if st.keeping && depth < st.keepDepth { + st.keeping = false + } + case scanBeginLiteral, scanContinue: + // starting or continuing a literal + if st.transformingValue { + buf.WriteByte(c) + continue + } else if st.key { + // it's a key + buf.WriteByte(c) + } else if !st.keeping { + // it's a value we're not keeping + if !st.wiped { + out.WriteString(`"?"`) + st.wiped = true + } + continue + } + case scanObjectKey: + // done scanning key + k := string(bytes.Trim(buf.Bytes(), `"`)) + if !st.keeping && p.keepKeys[k] { + // we should not obfuscate values of this key + st.keeping = true + st.keepDepth = depth + 1 + } else if !st.transformingValue && p.transformer != nil && p.transformKeys[k] { + // the string value immediately following this key will be passed through the value transformer + // if anything other than a literal is found then sql obfuscation is stopped and json obfuscation + // proceeds as usual + st.transformingValue = true + } + buf.Reset() + st.key = false + case scanSkipSpace: + continue + case scanError: + // we've encountered an error, mark that there might be more JSON + // using the ellipsis and return whatever we've managed to obfuscate + // thus far. + out.WriteString("...") + return out.String(), st.scan.err + } + out.WriteByte(c) + } + if st.scan.eof() == scanError { + // if an error occurred it's fine, simply add the ellipsis to indicate + // that the input has been truncated. + out.Write([]byte("...")) + return out.String(), st.scan.err + } + return out.String(), nil +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json_scanner.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json_scanner.go new file mode 100644 index 000000000..e642aa2c9 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json_scanner.go @@ -0,0 +1,560 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +// The code that follows is copied from go/src/encoding/json/scanner.go +// It may contain minor edits, such as allowing multiple JSON objects within +// the same input string (see stateEndTop) +// + +package obfuscate + +import "strconv" + +// A SyntaxError is a description of a JSON syntax error. +type SyntaxError struct { + msg string // description of error + Offset int64 // error occurred after reading Offset bytes +} + +func (e *SyntaxError) Error() string { return e.msg } + +// A scanner is a JSON scanning state machine. +// Callers call scan.reset() and then pass bytes in one at a time +// by calling scan.step(&scan, c) for each byte. +// The return value, referred to as an opcode, tells the +// caller about significant parsing events like beginning +// and ending literals, objects, and arrays, so that the +// caller can follow along if it wishes. +// The return value scanEnd indicates that a single top-level +// JSON value has been completed, *before* the byte that +// just got passed in. (The indication must be delayed in order +// to recognize the end of numbers: is 123 a whole value or +// the beginning of 12345e+6?). +type scanner struct { + // The step is a func to be called to execute the next transition. + // Also tried using an integer constant and a single func + // with a switch, but using the func directly was 10% faster + // on a 64-bit Mac Mini, and it's nicer to read. + step func(*scanner, byte) int + + // Reached end of top-level value. + endTop bool + + // Stack of what we're in the middle of - array values, object keys, object values. + parseState []int + + // Error that happened, if any. + err error + + // total bytes consumed, updated by decoder.Decode + bytes int64 +} + +// These values are returned by the state transition functions +// assigned to scanner.state and the method scanner.eof. +// They give details about the current state of the scan that +// callers might be interested to know about. +// It is okay to ignore the return value of any particular +// call to scanner.state: if one call returns scanError, +// every subsequent call will return scanError too. +const ( + // Continue. + scanContinue = iota // uninteresting byte + scanBeginLiteral // end implied by next result != scanContinue + scanBeginObject // begin object + scanObjectKey // just finished object key (string) + scanObjectValue // just finished non-last object value + scanEndObject // end object (implies scanObjectValue if possible) + scanBeginArray // begin array + scanArrayValue // just finished array value + scanEndArray // end array (implies scanArrayValue if possible) + scanSkipSpace // space byte; can skip; known to be last "continue" result + + // Stop. + scanEnd // top-level value ended *before* this byte; known to be first "stop" result + scanError // hit an error, scanner.err. +) + +// These values are stored in the parseState stack. +// They give the current state of a composite value +// being scanned. If the parser is inside a nested value +// the parseState describes the nested state, outermost at entry 0. +const ( + parseObjectKey = iota // parsing object key (before colon) + parseObjectValue // parsing object value (after colon) + parseArrayValue // parsing array value +) + +// reset prepares the scanner for use. +// It must be called before calling s.step. +func (s *scanner) reset() { + s.step = stateBeginValue + s.parseState = s.parseState[0:0] + s.err = nil + s.endTop = false +} + +// eof tells the scanner that the end of input has been reached. +// It returns a scan status just as s.step does. +func (s *scanner) eof() int { + if s.err != nil { + return scanError + } + if s.endTop { + return scanEnd + } + s.step(s, ' ') + if s.endTop { + return scanEnd + } + if s.err == nil { + s.err = &SyntaxError{"unexpected end of JSON input", s.bytes} + } + return scanError +} + +// pushParseState pushes a new parse state p onto the parse stack. +func (s *scanner) pushParseState(p int) { + s.parseState = append(s.parseState, p) +} + +// popParseState pops a parse state (already obtained) off the stack +// and updates s.step accordingly. +func (s *scanner) popParseState() { + n := len(s.parseState) - 1 + if n == 0 { + s.step = stateEndTop + s.endTop = true + return + } + s.parseState = s.parseState[0:n] + s.step = stateEndValue +} + +func isSpace(c byte) bool { + return c == ' ' || c == '\t' || c == '\r' || c == '\n' +} + +// stateBeginValueOrEmpty is the state after reading `[`. +func stateBeginValueOrEmpty(s *scanner, c byte) int { + if c <= ' ' && isSpace(c) { + return scanSkipSpace + } + if c == ']' { + return stateEndValue(s, c) + } + return stateBeginValue(s, c) +} + +// stateBeginValue is the state at the beginning of the input. +func stateBeginValue(s *scanner, c byte) int { + if c <= ' ' && isSpace(c) { + return scanSkipSpace + } + switch c { + case '{': + s.step = stateBeginStringOrEmpty + s.pushParseState(parseObjectKey) + return scanBeginObject + case '[': + s.step = stateBeginValueOrEmpty + s.pushParseState(parseArrayValue) + return scanBeginArray + case '"': + s.step = stateInString + return scanBeginLiteral + case '-': + s.step = stateNeg + return scanBeginLiteral + case '0': // beginning of 0.123 + s.step = state0 + return scanBeginLiteral + case 't': // beginning of true + s.step = stateT + return scanBeginLiteral + case 'f': // beginning of false + s.step = stateF + return scanBeginLiteral + case 'n': // beginning of null + s.step = stateN + return scanBeginLiteral + } + if '1' <= c && c <= '9' { // beginning of 1234.5 + s.step = state1 + return scanBeginLiteral + } + return s.error(c, "looking for beginning of value") +} + +// stateBeginStringOrEmpty is the state after reading `{`. +func stateBeginStringOrEmpty(s *scanner, c byte) int { + if c <= ' ' && isSpace(c) { + return scanSkipSpace + } + n := len(s.parseState) + if c == '}' && n > 0 { + s.parseState[n-1] = parseObjectValue + return stateEndValue(s, c) + } + return stateBeginString(s, c) +} + +// stateBeginString is the state after reading `{"key": value,`. +func stateBeginString(s *scanner, c byte) int { + if c <= ' ' && isSpace(c) { + return scanSkipSpace + } + if c == '"' { + s.step = stateInString + return scanBeginLiteral + } + return s.error(c, "looking for beginning of object key string") +} + +// stateEndValue is the state after completing a value, +// such as after reading `{}` or `true` or `["x"`. +func stateEndValue(s *scanner, c byte) int { + n := len(s.parseState) + if n == 0 { + // Completed top-level before the current byte. + s.step = stateEndTop + s.endTop = true + return stateEndTop(s, c) + } + if c <= ' ' && isSpace(c) { + s.step = stateEndValue + return scanSkipSpace + } + ps := s.parseState[n-1] + switch ps { + case parseObjectKey: + if c == ':' { + s.parseState[n-1] = parseObjectValue + s.step = stateBeginValue + return scanObjectKey + } + return s.error(c, "after object key") + case parseObjectValue: + if c == ',' { + s.parseState[n-1] = parseObjectKey + s.step = stateBeginString + return scanObjectValue + } + if c == '}' { + s.popParseState() + return scanEndObject + } + return s.error(c, "after object key:value pair") + case parseArrayValue: + if c == ',' { + s.step = stateBeginValue + return scanArrayValue + } + if c == ']' { + s.popParseState() + return scanEndArray + } + return s.error(c, "after array element") + } + return s.error(c, "") +} + +// stateEndTop is the state after finishing the top-level value, +// such as after reading `{}` or `[1,2,3]`. +// Only space characters should be seen now. +func stateEndTop(s *scanner, c byte) int { + if c != ' ' && c != '\t' && c != '\r' && c != '\n' { + // The former behaviour has been removed. Now, if anything + // other than whitespace follows, we assume a new JSON string + // might be starting. This allows us to continue obfuscating + // further strings in cases where there are multiple JSON + // objects enumerated sequentially within the same input. + // This is a common case for ElasticSearch response bodies. + s.reset() + return s.step(s, c) + } + return scanEnd +} + +// stateInString is the state after reading `"`. +func stateInString(s *scanner, c byte) int { + if c == '"' { + s.step = stateEndValue + return scanContinue + } + if c == '\\' { + s.step = stateInStringEsc + return scanContinue + } + if c < 0x20 { + return s.error(c, "in string literal") + } + return scanContinue +} + +// stateInStringEsc is the state after reading `"\` during a quoted string. +func stateInStringEsc(s *scanner, c byte) int { + switch c { + case 'b', 'f', 'n', 'r', 't', '\\', '/', '"': + s.step = stateInString + return scanContinue + case 'u': + s.step = stateInStringEscU + return scanContinue + } + return s.error(c, "in string escape code") +} + +// stateInStringEscU is the state after reading `"\u` during a quoted string. +func stateInStringEscU(s *scanner, c byte) int { + if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' { + s.step = stateInStringEscU1 + return scanContinue + } + // numbers + return s.error(c, "in \\u hexadecimal character escape") +} + +// stateInStringEscU1 is the state after reading `"\u1` during a quoted string. +func stateInStringEscU1(s *scanner, c byte) int { + if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' { + s.step = stateInStringEscU12 + return scanContinue + } + // numbers + return s.error(c, "in \\u hexadecimal character escape") +} + +// stateInStringEscU12 is the state after reading `"\u12` during a quoted string. +func stateInStringEscU12(s *scanner, c byte) int { + if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' { + s.step = stateInStringEscU123 + return scanContinue + } + // numbers + return s.error(c, "in \\u hexadecimal character escape") +} + +// stateInStringEscU123 is the state after reading `"\u123` during a quoted string. +func stateInStringEscU123(s *scanner, c byte) int { + if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' { + s.step = stateInString + return scanContinue + } + // numbers + return s.error(c, "in \\u hexadecimal character escape") +} + +// stateNeg is the state after reading `-` during a number. +func stateNeg(s *scanner, c byte) int { + if c == '0' { + s.step = state0 + return scanContinue + } + if '1' <= c && c <= '9' { + s.step = state1 + return scanContinue + } + return s.error(c, "in numeric literal") +} + +// state1 is the state after reading a non-zero integer during a number, +// such as after reading `1` or `100` but not `0`. +func state1(s *scanner, c byte) int { + if '0' <= c && c <= '9' { + s.step = state1 + return scanContinue + } + return state0(s, c) +} + +// state0 is the state after reading `0` during a number. +func state0(s *scanner, c byte) int { + if c == '.' { + s.step = stateDot + return scanContinue + } + if c == 'e' || c == 'E' { + s.step = stateE + return scanContinue + } + return stateEndValue(s, c) +} + +// stateDot is the state after reading the integer and decimal point in a number, +// such as after reading `1.`. +func stateDot(s *scanner, c byte) int { + if '0' <= c && c <= '9' { + s.step = stateDot0 + return scanContinue + } + return s.error(c, "after decimal point in numeric literal") +} + +// stateDot0 is the state after reading the integer, decimal point, and subsequent +// digits of a number, such as after reading `3.14`. +func stateDot0(s *scanner, c byte) int { + if '0' <= c && c <= '9' { + return scanContinue + } + if c == 'e' || c == 'E' { + s.step = stateE + return scanContinue + } + return stateEndValue(s, c) +} + +// stateE is the state after reading the mantissa and e in a number, +// such as after reading `314e` or `0.314e`. +func stateE(s *scanner, c byte) int { + if c == '+' || c == '-' { + s.step = stateESign + return scanContinue + } + return stateESign(s, c) +} + +// stateESign is the state after reading the mantissa, e, and sign in a number, +// such as after reading `314e-` or `0.314e+`. +func stateESign(s *scanner, c byte) int { + if '0' <= c && c <= '9' { + s.step = stateE0 + return scanContinue + } + return s.error(c, "in exponent of numeric literal") +} + +// stateE0 is the state after reading the mantissa, e, optional sign, +// and at least one digit of the exponent in a number, +// such as after reading `314e-2` or `0.314e+1` or `3.14e0`. +func stateE0(s *scanner, c byte) int { + if '0' <= c && c <= '9' { + return scanContinue + } + return stateEndValue(s, c) +} + +// stateT is the state after reading `t`. +func stateT(s *scanner, c byte) int { + if c == 'r' { + s.step = stateTr + return scanContinue + } + return s.error(c, "in literal true (expecting 'r')") +} + +// stateTr is the state after reading `tr`. +func stateTr(s *scanner, c byte) int { + if c == 'u' { + s.step = stateTru + return scanContinue + } + return s.error(c, "in literal true (expecting 'u')") +} + +// stateTru is the state after reading `tru`. +func stateTru(s *scanner, c byte) int { + if c == 'e' { + s.step = stateEndValue + return scanContinue + } + return s.error(c, "in literal true (expecting 'e')") +} + +// stateF is the state after reading `f`. +func stateF(s *scanner, c byte) int { + if c == 'a' { + s.step = stateFa + return scanContinue + } + return s.error(c, "in literal false (expecting 'a')") +} + +// stateFa is the state after reading `fa`. +func stateFa(s *scanner, c byte) int { + if c == 'l' { + s.step = stateFal + return scanContinue + } + return s.error(c, "in literal false (expecting 'l')") +} + +// stateFal is the state after reading `fal`. +func stateFal(s *scanner, c byte) int { + if c == 's' { + s.step = stateFals + return scanContinue + } + return s.error(c, "in literal false (expecting 's')") +} + +// stateFals is the state after reading `fals`. +func stateFals(s *scanner, c byte) int { + if c == 'e' { + s.step = stateEndValue + return scanContinue + } + return s.error(c, "in literal false (expecting 'e')") +} + +// stateN is the state after reading `n`. +func stateN(s *scanner, c byte) int { + if c == 'u' { + s.step = stateNu + return scanContinue + } + return s.error(c, "in literal null (expecting 'u')") +} + +// stateNu is the state after reading `nu`. +func stateNu(s *scanner, c byte) int { + if c == 'l' { + s.step = stateNul + return scanContinue + } + return s.error(c, "in literal null (expecting 'l')") +} + +// stateNul is the state after reading `nul`. +func stateNul(s *scanner, c byte) int { + if c == 'l' { + s.step = stateEndValue + return scanContinue + } + return s.error(c, "in literal null (expecting 'l')") +} + +// stateError is the state after reaching a syntax error, +// such as after reading `[1}` or `5.1.2`. +func stateError(s *scanner, c byte) int { + return scanError +} + +// error records an error and switches to the error state. +func (s *scanner) error(c byte, context string) int { + s.step = stateError + s.err = &SyntaxError{"invalid character " + quoteChar(c) + " " + context, s.bytes} + return scanError +} + +// quoteChar formats c as a quoted character literal +func quoteChar(c byte) string { + // special cases - different from quoted strings + if c == '\'' { + return `'\''` + } + if c == '"' { + return `'"'` + } + + // use quoted string with different quotation marks + s := strconv.Quote(string(c)) + return "'" + s[1:len(s)-1] + "'" +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/memcached.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/memcached.go new file mode 100644 index 000000000..ce5cfe3fd --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/memcached.go @@ -0,0 +1,19 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package obfuscate + +import "strings" + +// ObfuscateMemcachedString obfuscates the Memcached command cmd. +func (*Obfuscator) ObfuscateMemcachedString(cmd string) string { + // All memcached commands end with new lines [1]. In the case of storage + // commands, key values follow after. Knowing this, all we have to do + // to obfuscate sensitive information is to remove everything that follows + // a new line. For non-storage commands, this will have no effect. + // [1]: https://github.com/memcached/memcached/blob/master/doc/protocol.txt + out := strings.SplitN(cmd, "\r\n", 2)[0] + return strings.TrimSpace(out) +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/obfuscate.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/obfuscate.go new file mode 100644 index 000000000..62ad512bd --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/obfuscate.go @@ -0,0 +1,267 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +// Package obfuscate implements quantizing and obfuscating of tags and resources for +// a set of spans matching a certain criteria. +// +// This module is used in the Datadog Agent, the Go tracing client (dd-trace-go) and in the +// OpenTelemetry Collector Datadog exporter./ End-user behavior is stable, but there are no +// stability guarantees on its public Go API. Nonetheless, if editing try to avoid breaking +// API changes if possible and double check the API usage on all module dependents. +package obfuscate + +import ( + "bytes" + + "github.com/DataDog/datadog-go/v5/statsd" + "go.uber.org/atomic" +) + +// Obfuscator quantizes and obfuscates spans. The obfuscator is not safe for +// concurrent use. +type Obfuscator struct { + opts *Config + es *jsonObfuscator // nil if disabled + mongo *jsonObfuscator // nil if disabled + sqlExecPlan *jsonObfuscator // nil if disabled + sqlExecPlanNormalize *jsonObfuscator // nil if disabled + // sqlLiteralEscapes reports whether we should treat escape characters literally or as escape characters. + // Different SQL engines behave in different ways and the tokenizer needs to be generic. + sqlLiteralEscapes *atomic.Bool + // queryCache keeps a cache of already obfuscated queries. + queryCache *measuredCache + log Logger +} + +// Logger is able to log certain log messages. +type Logger interface { + // Debugf logs the given message using the given format. + Debugf(format string, params ...interface{}) +} + +type noopLogger struct{} + +func (noopLogger) Debugf(_ string, _ ...interface{}) {} + +// setSQLLiteralEscapes sets whether or not escape characters should be treated literally by the SQL obfuscator. +func (o *Obfuscator) setSQLLiteralEscapes(ok bool) { + if ok { + o.sqlLiteralEscapes.Store(true) + } else { + o.sqlLiteralEscapes.Store(false) + } +} + +// useSQLLiteralEscapes reports whether escape characters will be treated literally by the SQL obfuscator. +// Some SQL engines require it and others don't. It will be detected as SQL queries are being obfuscated +// through calls to ObfuscateSQLString and automatically set for future. +func (o *Obfuscator) useSQLLiteralEscapes() bool { + return o.sqlLiteralEscapes.Load() +} + +// Config holds the configuration for obfuscating sensitive data for various span types. +type Config struct { + // SQL holds the obfuscation configuration for SQL queries. + SQL SQLConfig + + // ES holds the obfuscation configuration for ElasticSearch bodies. + ES JSONConfig + + // Mongo holds the obfuscation configuration for MongoDB queries. + Mongo JSONConfig + + // SQLExecPlan holds the obfuscation configuration for SQL Exec Plans. This is strictly for safety related obfuscation, + // not normalization. Normalization of exec plans is configured in SQLExecPlanNormalize. + SQLExecPlan JSONConfig + + // SQLExecPlanNormalize holds the normalization configuration for SQL Exec Plans. + SQLExecPlanNormalize JSONConfig + + // HTTP holds the obfuscation settings for HTTP URLs. + HTTP HTTPConfig + + // Redis holds the obfuscation settings for Redis commands. + Redis RedisConfig + + // Statsd specifies the statsd client to use for reporting metrics. + Statsd StatsClient + + // Logger specifies the logger to use when outputting messages. + // If unset, no logs will be outputted. + Logger Logger +} + +// StatsClient implementations are able to emit stats. +type StatsClient interface { + // Gauge reports a gauge stat with the given name, value, tags and rate. + Gauge(name string, value float64, tags []string, rate float64) error +} + +// SQLConfig holds the config for obfuscating SQL. +type SQLConfig struct { + // DBMS identifies the type of database management system (e.g. MySQL, Postgres, and SQL Server). + // Valid values for this can be found at https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md#connection-level-attributes + DBMS string `json:"dbms"` + + // TableNames specifies whether the obfuscator should also extract the table names that a query addresses, + // in addition to obfuscating. + TableNames bool `json:"table_names" yaml:"table_names"` + + // CollectCommands specifies whether the obfuscator should extract and return commands as SQL metadata when obfuscating. + CollectCommands bool `json:"collect_commands" yaml:"collect_commands"` + + // CollectComments specifies whether the obfuscator should extract and return comments as SQL metadata when obfuscating. + CollectComments bool `json:"collect_comments" yaml:"collect_comments"` + + // ReplaceDigits specifies whether digits in table names and identifiers should be obfuscated. + ReplaceDigits bool `json:"replace_digits" yaml:"replace_digits"` + + // KeepSQLAlias reports whether SQL aliases ("AS") should be truncated. + KeepSQLAlias bool `json:"keep_sql_alias"` + + // DollarQuotedFunc reports whether to treat "$func$" delimited dollar-quoted strings + // differently and not obfuscate them as a string. To read more about dollar quoted + // strings see: + // + // https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING + DollarQuotedFunc bool `json:"dollar_quoted_func"` + + // Cache reports whether the obfuscator should use a LRU look-up cache for SQL obfuscations. + Cache bool +} + +// SQLMetadata holds metadata collected throughout the obfuscation of an SQL statement. It is only +// collected when enabled via SQLConfig. +type SQLMetadata struct { + // Size holds the byte size of the metadata collected. + Size int64 + // TablesCSV is a comma-separated list of tables that the query addresses. + TablesCSV string `json:"tables_csv"` + // Commands holds commands executed in an SQL statement. + // e.g. SELECT, UPDATE, INSERT, DELETE, etc. + Commands []string `json:"commands"` + // Comments holds comments in an SQL statement. + Comments []string `json:"comments"` +} + +// HTTPConfig holds the configuration settings for HTTP obfuscation. +type HTTPConfig struct { + // RemoveQueryStrings determines query strings to be removed from HTTP URLs. + RemoveQueryString bool + + // RemovePathDigits determines digits in path segments to be obfuscated. + RemovePathDigits bool +} + +// RedisConfig holds the configuration settings for Redis obfuscation +type RedisConfig struct { + // Enabled specifies whether this feature should be enabled. + Enabled bool + + // RemoveAllArgs specifies whether all arguments to a given Redis + // command should be obfuscated. + RemoveAllArgs bool +} + +// JSONConfig holds the obfuscation configuration for sensitive +// data found in JSON objects. +type JSONConfig struct { + // Enabled will specify whether obfuscation should be enabled. + Enabled bool + + // KeepValues will specify a set of keys for which their values will + // not be obfuscated. + KeepValues []string + + // ObfuscateSQLValues will specify a set of keys for which their values + // will be passed through SQL obfuscation + ObfuscateSQLValues []string +} + +// NewObfuscator creates a new obfuscator +func NewObfuscator(cfg Config) *Obfuscator { + if cfg.Logger == nil { + cfg.Logger = noopLogger{} + } + o := Obfuscator{ + opts: &cfg, + queryCache: newMeasuredCache(cacheOptions{On: cfg.SQL.Cache, Statsd: cfg.Statsd}), + sqlLiteralEscapes: atomic.NewBool(false), + log: cfg.Logger, + } + if cfg.ES.Enabled { + o.es = newJSONObfuscator(&cfg.ES, &o) + } + if cfg.Mongo.Enabled { + o.mongo = newJSONObfuscator(&cfg.Mongo, &o) + } + if cfg.SQLExecPlan.Enabled { + o.sqlExecPlan = newJSONObfuscator(&cfg.SQLExecPlan, &o) + } + if cfg.SQLExecPlanNormalize.Enabled { + o.sqlExecPlanNormalize = newJSONObfuscator(&cfg.SQLExecPlanNormalize, &o) + } + if cfg.Statsd == nil { + cfg.Statsd = &statsd.NoOpClient{} + } + return &o +} + +// Stop cleans up after a finished Obfuscator. +func (o *Obfuscator) Stop() { + o.queryCache.Close() +} + +// compactWhitespaces compacts all whitespaces in t. +func compactWhitespaces(t string) string { + n := len(t) + r := make([]byte, n) + spaceCode := uint8(32) + isWhitespace := func(char uint8) bool { return char == spaceCode } + nr := 0 + offset := 0 + for i := 0; i < n; i++ { + if isWhitespace(t[i]) { + copy(r[nr:], t[nr+offset:i]) + r[i-offset] = spaceCode + nr = i + 1 - offset + for j := i + 1; j < n; j++ { + if !isWhitespace(t[j]) { + offset += j - i - 1 + i = j + break + } else if j == n-1 { + offset += j - i + i = j + break + } + } + } + } + copy(r[nr:], t[nr+offset:n]) + r = r[:n-offset] + return string(bytes.Trim(r, " ")) +} + +// replaceDigits replaces consecutive sequences of digits with '?', +// example: "jobs_2020_1597876964" --> "jobs_?_?" +func replaceDigits(buffer []byte) []byte { + scanningDigit := false + filtered := buffer[:0] + for _, b := range buffer { + // digits are encoded as 1 byte in utf8 + if isDigit(rune(b)) { + if scanningDigit { + continue + } + scanningDigit = true + filtered = append(filtered, byte('?')) + continue + } + scanningDigit = false + filtered = append(filtered, b) + } + return filtered +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis.go new file mode 100644 index 000000000..f1cacac15 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis.go @@ -0,0 +1,301 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package obfuscate + +import ( + "strings" +) + +// redisTruncationMark is used as suffix by tracing libraries to indicate that a +// command was truncated. +const redisTruncationMark = "..." + +const maxRedisNbCommands = 3 + +// Redis commands consisting in 2 words +var redisCompoundCommandSet = map[string]bool{ + "CLIENT": true, "CLUSTER": true, "COMMAND": true, "CONFIG": true, "DEBUG": true, "SCRIPT": true} + +// QuantizeRedisString returns a quantized version of a Redis query. +// +// TODO(gbbr): Refactor this method to use the tokenizer and +// remove "compactWhitespaces". This method is buggy when commands +// contain quoted strings with newlines. +func (*Obfuscator) QuantizeRedisString(query string) string { + query = compactWhitespaces(query) + + var resource strings.Builder + truncated := false + nbCmds := 0 + + for len(query) > 0 && nbCmds < maxRedisNbCommands { + var rawLine string + + // Read the next command + idx := strings.IndexByte(query, '\n') + if idx == -1 { + rawLine = query + query = "" + } else { + rawLine = query[:idx] + query = query[idx+1:] + } + + line := strings.Trim(rawLine, " ") + if len(line) == 0 { + continue + } + + // Parse arguments + args := strings.SplitN(line, " ", 3) + + if strings.HasSuffix(args[0], redisTruncationMark) { + truncated = true + continue + } + + command := strings.ToUpper(args[0]) + + if redisCompoundCommandSet[command] && len(args) > 1 { + if strings.HasSuffix(args[1], redisTruncationMark) { + truncated = true + continue + } + + command += " " + strings.ToUpper(args[1]) + } + + // Write the command representation + resource.WriteByte(' ') + resource.WriteString(command) + + nbCmds++ + truncated = false + } + + if nbCmds == maxRedisNbCommands || truncated { + resource.WriteString(" ...") + } + + return strings.Trim(resource.String(), " ") +} + +// ObfuscateRedisString obfuscates the given Redis command. +func (*Obfuscator) ObfuscateRedisString(rediscmd string) string { + t := newRedisTokenizer([]byte(rediscmd)) + var ( + str strings.Builder + cmd string + args []string + ) + for { + tok, typ, done := t.scan() + switch typ { + case redisTokenCommand: + // new command starting + if cmd != "" { + // a previous command was buffered, obfuscate it + obfuscateRedisCmd(&str, cmd, args...) + str.WriteByte('\n') + } + cmd = tok + args = args[:0] + case redisTokenArgument: + args = append(args, tok) + } + if done { + // last command + obfuscateRedisCmd(&str, cmd, args...) + break + } + } + return str.String() +} + +func obfuscateRedisCmd(out *strings.Builder, cmd string, args ...string) { + out.WriteString(cmd) + if len(args) == 0 { + return + } + out.WriteByte(' ') + + switch strings.ToUpper(cmd) { + case "AUTH": + // Obfuscate everything after command + // • AUTH password + if len(args) > 0 { + args[0] = "?" + args = args[:1] + } + + case "APPEND", "GETSET", "LPUSHX", "GEORADIUSBYMEMBER", "RPUSHX", + "SET", "SETNX", "SISMEMBER", "ZRANK", "ZREVRANK", "ZSCORE": + // Obfuscate 2nd argument: + // • APPEND key value + // • GETSET key value + // • LPUSHX key value + // • GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] + // • RPUSHX key value + // • SET key value [expiration EX seconds|PX milliseconds] [NX|XX] + // • SETNX key value + // • SISMEMBER key member + // • ZRANK key member + // • ZREVRANK key member + // • ZSCORE key member + obfuscateRedisArgN(args, 1) + + case "HSET", "HSETNX", "LREM", "LSET", "SETBIT", "SETEX", "PSETEX", + "SETRANGE", "ZINCRBY", "SMOVE", "RESTORE": + // Obfuscate 3rd argument: + // • HSET key field value + // • HSETNX key field value + // • LREM key count value + // • LSET key index value + // • SETBIT key offset value + // • SETEX key seconds value + // • PSETEX key milliseconds value + // • SETRANGE key offset value + // • ZINCRBY key increment member + // • SMOVE source destination member + // • RESTORE key ttl serialized-value [REPLACE] + obfuscateRedisArgN(args, 2) + + case "LINSERT": + // Obfuscate 4th argument: + // • LINSERT key BEFORE|AFTER pivot value + obfuscateRedisArgN(args, 3) + + case "GEOHASH", "GEOPOS", "GEODIST", "LPUSH", "RPUSH", "SREM", + "ZREM", "SADD": + // Obfuscate all arguments after the first one. + // • GEOHASH key member [member ...] + // • GEOPOS key member [member ...] + // • GEODIST key member1 member2 [unit] + // • LPUSH key value [value ...] + // • RPUSH key value [value ...] + // • SREM key member [member ...] + // • ZREM key member [member ...] + // • SADD key member [member ...] + if len(args) > 1 { + args[1] = "?" + args = args[:2] + } + + case "GEOADD": + // Obfuscating every 3rd argument starting from first + // • GEOADD key longitude latitude member [longitude latitude member ...] + obfuscateRedisArgsStep(args, 1, 3) + + case "HMSET": + // Every 2nd argument starting from first. + // • HMSET key field value [field value ...] + obfuscateRedisArgsStep(args, 1, 2) + + case "MSET", "MSETNX": + // Every 2nd argument starting from command. + // • MSET key value [key value ...] + // • MSETNX key value [key value ...] + obfuscateRedisArgsStep(args, 0, 2) + + case "CONFIG": + // Obfuscate 2nd argument to SET sub-command. + // • CONFIG SET parameter value + if strings.ToUpper(args[0]) == "SET" { + obfuscateRedisArgN(args, 2) + } + + case "BITFIELD": + // Obfuscate 3rd argument to SET sub-command: + // • BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL] + var n int + for i, arg := range args { + if strings.ToUpper(arg) == "SET" { + n = i + } + if n > 0 && i-n == 3 { + args[i] = "?" + break + } + } + + case "ZADD": + // Obfuscate every 2nd argument after potential optional ones. + // • ZADD key [NX|XX] [CH] [INCR] score member [score member ...] + var i int + loop: + for i = range args { + if i == 0 { + continue // key + } + switch args[i] { + case "NX", "XX", "CH", "INCR": + // continue + default: + break loop + } + } + obfuscateRedisArgsStep(args, i, 2) + + default: + // Obfuscate nothing. + } + out.WriteString(strings.Join(args, " ")) +} + +// removeAllRedisArgs will take in a command and obfuscate all arguments following +// the command, regardless of if the command is valid Redis or not +func (*Obfuscator) RemoveAllRedisArgs(rediscmd string) string { + fullCmd := strings.Fields(rediscmd) + if len(fullCmd) == 0 { + return "" + } + cmd, args := fullCmd[0], fullCmd[1:] + + var out strings.Builder + out.WriteString(cmd) + if len(args) == 0 { + return out.String() + } + + out.WriteByte(' ') + switch strings.ToUpper(cmd) { + case "BITFIELD": + out.WriteString("?") + for _, a := range args { + arg := strings.ToUpper(a) + if arg == "SET" || arg == "GET" || arg == "INCRBY" { + out.WriteString(strings.Join([]string{"", a, "?"}, " ")) + } + } + case "CONFIG": + arg := strings.ToUpper(args[0]) + if arg == "GET" || arg == "SET" || arg == "RESETSTAT" || arg == "REWRITE" { + out.WriteString(strings.Join([]string{args[0], "?"}, " ")) + } else { + out.WriteString("?") + } + default: + out.WriteString("?") + } + + return out.String() +} + +func obfuscateRedisArgN(args []string, n int) { + if len(args) > n { + args[n] = "?" + } +} + +func obfuscateRedisArgsStep(args []string, start, step int) { + if start+step-1 >= len(args) { + // can't reach target + return + } + for i := start + step - 1; i < len(args); i += step { + args[i] = "?" + } +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis_tokenizer.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis_tokenizer.go new file mode 100644 index 000000000..d4ef2dc33 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis_tokenizer.go @@ -0,0 +1,187 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package obfuscate + +import ( + "bytes" + "strings" +) + +// redisTokenType specifies the token type returned by the tokenizer. +type redisTokenType int + +const ( + // redisTokenCommand is a command token. For compound tokens, it is + // only the first part up to a space. + redisTokenCommand redisTokenType = iota + + // redisTokenArgument is an argument token. + redisTokenArgument +) + +// String implements fmt.Stringer. +func (t redisTokenType) String() string { + return map[redisTokenType]string{ + redisTokenCommand: "command", + redisTokenArgument: "argument", + }[t] +} + +// redisTokenizer tokenizes a Redis command string. The string can be on +// multiple lines. The tokenizer is capable of parsing quoted strings and escape +// sequences inside them. +type redisTokenizer struct { + data []byte + ch byte + off int + done bool + state redisParseState +} + +// redisParseState specifies the current state of the tokenizer. +type redisParseState int + +const ( + // redisStateCommand specifies that we are about to parse a command. + // It is usually the state at the beginning of the scan or after a + // new line. + redisStateCommand redisParseState = iota + + // redisStateArgument specifies that we are about to parse an argument + // to a command or the rest of the tokens in a compound command. + redisStateArgument +) + +// newRedisTokenizer returns a new tokenizer for the given data. +func newRedisTokenizer(data []byte) *redisTokenizer { + return &redisTokenizer{ + data: bytes.TrimSpace(data), + off: -1, + state: redisStateCommand, + } +} + +// scan returns the next token, it's type and a bool. The boolean specifies if +// the returned token was the last one. +func (t *redisTokenizer) scan() (tok string, typ redisTokenType, done bool) { + switch t.state { + case redisStateCommand: + return t.scanCommand() + default: + return t.scanArg() + } +} + +// next advances the scanner to the next character. +func (t *redisTokenizer) next() { + t.off++ + if t.off <= len(t.data)-1 { + t.ch = t.data[t.off] + return + } + t.done = true +} + +// scanCommand scans a command from the buffer. +func (t *redisTokenizer) scanCommand() (tok string, typ redisTokenType, done bool) { + var ( + str strings.Builder + started bool + ) + for { + t.next() + if t.done { + return str.String(), typ, t.done + } + switch t.ch { + case ' ': + if !started { + // skip spaces preceding token + t.skipSpace() + break + } + // done scanning command + t.state = redisStateArgument + t.skipSpace() + return str.String(), redisTokenCommand, t.done + case '\n': + return str.String(), redisTokenCommand, t.done + default: + str.WriteByte(t.ch) + } + started = true + } +} + +// scanArg scans an argument from the buffer. +func (t *redisTokenizer) scanArg() (tok string, typ redisTokenType, done bool) { + var ( + str strings.Builder + quoted bool // in quoted string + escape bool // escape sequence + ) + for { + t.next() + if t.done { + return str.String(), redisTokenArgument, t.done + } + switch t.ch { + case '\\': + str.WriteByte('\\') + if !escape { + // next character could be escaped + escape = true + continue + } + case '\n': + if !quoted { + // last argument, new command follows + t.state = redisStateCommand + return str.String(), redisTokenArgument, t.done + } + str.WriteByte('\n') + case '"': + str.WriteByte('"') + if !escape { + // this quote wasn't escaped, toggle quoted mode + quoted = !quoted + } + case ' ': + if !quoted { + t.skipSpace() + return str.String(), redisTokenArgument, t.done + } + str.WriteByte(' ') + default: + str.WriteByte(t.ch) + } + escape = false + } +} + +// unread is the reverse of next, unreading a character. +func (t *redisTokenizer) unread() { + if t.off < 1 { + return + } + t.off-- + t.ch = t.data[t.off] +} + +// skipSpace moves the cursor forward until it meets the last space +// in a sequence of contiguous spaces. +func (t *redisTokenizer) skipSpace() { + for t.ch == ' ' || t.ch == '\t' || t.ch == '\r' && !t.done { + t.next() + } + if t.ch == '\n' { + // next token is a command + t.state = redisStateCommand + } else { + // don't steal the first non-space character + t.unread() + } +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql.go new file mode 100644 index 000000000..2a3bbdee7 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql.go @@ -0,0 +1,416 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package obfuscate + +import ( + "bytes" + "errors" + "fmt" + "strings" + "unicode" + "unicode/utf8" +) + +var questionMark = []byte("?") + +// metadataFinderFilter is a filter which attempts to collect metadata from a query, such as comments and tables. +// It is meant to run before all the other filters. +type metadataFinderFilter struct { + collectTableNames bool + collectCommands bool + collectComments bool + replaceDigits bool + + // size holds the byte size of the metadata collected by the filter. + size int64 + // tablesSeen keeps track of unique table names encountered by the filter. + tablesSeen map[string]struct{} + // tablesCSV specifies a comma-separated list of tables. + tablesCSV strings.Builder + // commands keeps track of commands encountered by the filter. + commands []string + // comments keeps track of comments encountered by the filter. + comments []string +} + +func (f *metadataFinderFilter) Filter(token, lastToken TokenKind, buffer []byte) (TokenKind, []byte, error) { + if f.collectComments && token == Comment { + // A comment with line-breaks will be brought to a single line. + comment := strings.TrimSpace(strings.Replace(string(buffer), "\n", " ", -1)) + f.size += int64(len(comment)) + f.comments = append(f.comments, comment) + } + if f.collectCommands { + switch token { + case Select, Update, Insert, Delete, Join, Alter, Drop, Create, Grant, Revoke, Commit, Begin, Truncate: + command := strings.ToUpper(token.String()) + f.size += int64(len(command)) + f.commands = append(f.commands, command) + } + } + if f.collectTableNames { + switch lastToken { + case From, Join: + // SELECT ... FROM [tableName] + // DELETE FROM [tableName] + // ... JOIN [tableName] + if r, _ := utf8.DecodeRune(buffer); !unicode.IsLetter(r) { + // first character in buffer is not a letter; we might have a nested + // query like SELECT * FROM (SELECT ...) + break + } + fallthrough + case Update, Into: + // UPDATE [tableName] + // INSERT INTO [tableName] + tableName := string(buffer) + if f.replaceDigits { + tableNameCopy := make([]byte, len(buffer)) + copy(tableNameCopy, buffer) + tableName = string(replaceDigits(tableNameCopy)) + } + f.storeTableName(tableName) + return TableName, buffer, nil + } + } + return token, buffer, nil +} + +func (f *metadataFinderFilter) storeTableName(name string) { + if _, ok := f.tablesSeen[name]; ok { + return + } + if f.tablesSeen == nil { + f.tablesSeen = make(map[string]struct{}, 1) + } + f.tablesSeen[name] = struct{}{} + if f.tablesCSV.Len() > 0 { + f.size++ + f.tablesCSV.WriteByte(',') + } + f.size += int64(len(name)) + f.tablesCSV.WriteString(name) +} + +// Results returns metadata collected by the filter for an SQL statement. +func (f *metadataFinderFilter) Results() SQLMetadata { + return SQLMetadata{ + Size: f.size, + TablesCSV: f.tablesCSV.String(), + Commands: f.commands, + Comments: f.comments, + } +} + +// Reset implements tokenFilter. +func (f *metadataFinderFilter) Reset() { + for k := range f.tablesSeen { + delete(f.tablesSeen, k) + } + f.size = 0 + f.tablesCSV.Reset() + f.commands = f.commands[:0] + f.comments = f.comments[:0] +} + +// discardFilter is a token filter which discards certain elements from a query, such as +// comments and AS aliases by returning a nil buffer. +type discardFilter struct { + keepSQLAlias bool +} + +// Filter the given token so that a `nil` slice is returned if the token is in the token filtered list. +func (f *discardFilter) Filter(token, lastToken TokenKind, buffer []byte) (TokenKind, []byte, error) { + // filters based on previous token + switch lastToken { + case FilteredBracketedIdentifier: + if token != ']' { + // we haven't found the closing bracket yet, keep going + if token != ID { + // the token between the brackets *must* be an identifier, + // otherwise the query is invalid. + return LexError, nil, fmt.Errorf("expected identifier in bracketed filter, got %d", token) + } + return FilteredBracketedIdentifier, nil, nil + } + fallthrough + case As: + if token == '[' { + // the identifier followed by AS is an MSSQL bracketed identifier + // and will continue to be discarded until we find the corresponding + // closing bracket counter-part. See GitHub issue DataDog/datadog-trace-agent#475. + return FilteredBracketedIdentifier, nil, nil + } + if f.keepSQLAlias { + return token, buffer, nil + } + return Filtered, nil, nil + } + + // filters based on the current token; if the next token should be ignored, + // return the same token value (not FilteredGroupable) and nil + switch token { + case Comment: + return Filtered, nil, nil + case ';': + return markFilteredGroupable(token), nil, nil + case As: + if !f.keepSQLAlias { + return As, nil, nil + } + fallthrough + default: + return token, buffer, nil + } +} + +// Reset implements tokenFilter. +func (f *discardFilter) Reset() {} + +// replaceFilter is a token filter which obfuscates strings and numbers in queries by replacing them +// with the "?" character. +type replaceFilter struct { + replaceDigits bool +} + +// Filter the given token so that it will be replaced if in the token replacement list +func (f *replaceFilter) Filter(token, lastToken TokenKind, buffer []byte) (tokenType TokenKind, tokenBytes []byte, err error) { + switch lastToken { + case Savepoint: + return markFilteredGroupable(token), questionMark, nil + case '=': + switch token { + case DoubleQuotedString: + // double-quoted strings after assignments are eligible for obfuscation + return markFilteredGroupable(token), questionMark, nil + } + } + switch token { + case DollarQuotedString, String, Number, Null, Variable, PreparedStatement, BooleanLiteral, EscapeSequence: + return markFilteredGroupable(token), questionMark, nil + case '?': + // Cases like 'ARRAY [ ?, ? ]' should be collapsed into 'ARRAY [ ? ]' + return markFilteredGroupable(token), questionMark, nil + case TableName, ID: + if f.replaceDigits { + return token, replaceDigits(buffer), nil + } + fallthrough + default: + return token, buffer, nil + } +} + +// Reset implements tokenFilter. +func (f *replaceFilter) Reset() {} + +// groupingFilter is a token filter which groups together items replaced by the replaceFilter. It is meant +// to run immediately after it. +type groupingFilter struct { + groupFilter int // counts the number of values, e.g. 3 = ?, ?, ? + groupMulti int // counts the number of groups, e.g. 2 = (?, ?), (?, ?, ?) +} + +// Filter the given token so that it will be discarded if a grouping pattern +// has been recognized. A grouping is composed by items like: +// - '( ?, ?, ? )' +// - '( ?, ? ), ( ?, ? )' +func (f *groupingFilter) Filter(token, lastToken TokenKind, buffer []byte) (tokenType TokenKind, tokenBytes []byte, err error) { + // increasing the number of groups means that we're filtering an entire group + // because it can be represented with a single '( ? )' + if (lastToken == '(' && isFilteredGroupable(token)) || (token == '(' && f.groupMulti > 0) { + f.groupMulti++ + } + + // Potential commands that could indicate the start of a subquery. + isStartOfSubquery := token == Select || token == Delete || token == Update || token == ID + + switch { + case f.groupMulti > 0 && lastToken == FilteredGroupableParenthesis && isStartOfSubquery: + // this is the start of a new group that seems to be a nested query; + // cancel grouping. + f.Reset() + return token, append([]byte("( "), buffer...), nil + case isFilteredGroupable(token): + // the previous filter has dropped this token so we should start + // counting the group filter so that we accept only one '?' for + // the same group + f.groupFilter++ + + if f.groupFilter > 1 { + return markFilteredGroupable(token), nil, nil + } + case f.groupFilter > 0 && (token == ',' || token == '?'): + // if we are in a group drop all commas + return markFilteredGroupable(token), nil, nil + case f.groupMulti > 1: + // drop all tokens since we're in a counting group + // and they're duplicated + return markFilteredGroupable(token), nil, nil + case token != ',' && token != '(' && token != ')' && !isFilteredGroupable(token): + // when we're out of a group reset the filter state + f.Reset() + } + + return token, buffer, nil +} + +// isFilteredGroupable reports whether token is to be considered filtered groupable. +func isFilteredGroupable(token TokenKind) bool { + switch token { + case FilteredGroupable, FilteredGroupableParenthesis: + return true + default: + return false + } +} + +// markFilteredGroupable returns the appropriate TokenKind to mark this token as +// filtered groupable. +func markFilteredGroupable(token TokenKind) TokenKind { + switch token { + case '(': + return FilteredGroupableParenthesis + default: + return FilteredGroupable + } +} + +// Reset resets the groupingFilter so that it may be used again. +func (f *groupingFilter) Reset() { + f.groupFilter = 0 + f.groupMulti = 0 +} + +// ObfuscateSQLString quantizes and obfuscates the given input SQL query string. Quantization removes +// some elements such as comments and aliases and obfuscation attempts to hide sensitive information +// in strings and numbers by redacting them. +func (o *Obfuscator) ObfuscateSQLString(in string) (*ObfuscatedQuery, error) { + return o.ObfuscateSQLStringWithOptions(in, &o.opts.SQL) +} + +// ObfuscateSQLStringWithOptions accepts an optional SQLOptions to change the behavior of the obfuscator +// to quantize and obfuscate the given input SQL query string. Quantization removes some elements such as comments +// and aliases and obfuscation attempts to hide sensitive information in strings and numbers by redacting them. +func (o *Obfuscator) ObfuscateSQLStringWithOptions(in string, opts *SQLConfig) (*ObfuscatedQuery, error) { + if v, ok := o.queryCache.Get(in); ok { + return v.(*ObfuscatedQuery), nil + } + oq, err := o.obfuscateSQLString(in, opts) + if err != nil { + return oq, err + } + o.queryCache.Set(in, oq, oq.Cost()) + return oq, nil +} + +func (o *Obfuscator) obfuscateSQLString(in string, opts *SQLConfig) (*ObfuscatedQuery, error) { + lesc := o.useSQLLiteralEscapes() + tok := NewSQLTokenizer(in, lesc, opts) + out, err := attemptObfuscation(tok) + if err != nil && tok.SeenEscape() { + // If the tokenizer failed, but saw an escape character in the process, + // try again treating escapes differently + tok = NewSQLTokenizer(in, !lesc, opts) + if out, err2 := attemptObfuscation(tok); err2 == nil { + // If the second attempt succeeded, change the default behavior so that + // on the next run we get it right in the first run. + o.setSQLLiteralEscapes(!lesc) + return out, nil + } + } + return out, err +} + +// ObfuscatedQuery specifies information about an obfuscated SQL query. +type ObfuscatedQuery struct { + Query string `json:"query"` // the obfuscated SQL query + Metadata SQLMetadata `json:"metadata"` // metadata extracted from the SQL query +} + +// Cost returns the number of bytes needed to store all the fields +// of this ObfuscatedQuery. +func (oq *ObfuscatedQuery) Cost() int64 { + return int64(len(oq.Query)) + oq.Metadata.Size +} + +// attemptObfuscation attempts to obfuscate the SQL query loaded into the tokenizer, using the given set of filters. +func attemptObfuscation(tokenizer *SQLTokenizer) (*ObfuscatedQuery, error) { + var ( + out = bytes.NewBuffer(make([]byte, 0, len(tokenizer.buf))) + err error + lastToken TokenKind + metadata = metadataFinderFilter{ + collectTableNames: tokenizer.cfg.TableNames, + collectCommands: tokenizer.cfg.CollectCommands, + collectComments: tokenizer.cfg.CollectComments, + replaceDigits: tokenizer.cfg.ReplaceDigits, + } + discard = discardFilter{keepSQLAlias: tokenizer.cfg.KeepSQLAlias} + replace = replaceFilter{replaceDigits: tokenizer.cfg.ReplaceDigits} + grouping groupingFilter + ) + defer metadata.Reset() + // call Scan() function until tokens are available or if a LEX_ERROR is raised. After + // retrieving a token, send it to the tokenFilter chains so that the token is discarded + // or replaced. + for { + token, buff := tokenizer.Scan() + if token == EndChar { + break + } + if token == LexError { + return nil, fmt.Errorf("%v", tokenizer.Err()) + } + + if token, buff, err = metadata.Filter(token, lastToken, buff); err != nil { + return nil, err + } + if token, buff, err = discard.Filter(token, lastToken, buff); err != nil { + return nil, err + } + if token, buff, err = replace.Filter(token, lastToken, buff); err != nil { + return nil, err + } + if token, buff, err = grouping.Filter(token, lastToken, buff); err != nil { + return nil, err + } + if buff != nil { + if out.Len() != 0 { + switch token { + case ',': + case '=': + if lastToken == ':' { + // do not add a space before an equals if a colon was + // present before it. + break + } + fallthrough + default: + out.WriteRune(' ') + } + } + out.Write(buff) + } + lastToken = token + } + if out.Len() == 0 { + return nil, errors.New("result is empty") + } + return &ObfuscatedQuery{ + Query: out.String(), + Metadata: metadata.Results(), + }, nil +} + +// ObfuscateSQLExecPlan obfuscates query conditions in the provided JSON encoded execution plan. If normalize=True, +// then cost and row estimates are also obfuscated away. +func (o *Obfuscator) ObfuscateSQLExecPlan(jsonPlan string, normalize bool) (string, error) { + if normalize { + return o.sqlExecPlanNormalize.obfuscate([]byte(jsonPlan)) + } + return o.sqlExecPlan.obfuscate([]byte(jsonPlan)) +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql_tokenizer.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql_tokenizer.go new file mode 100644 index 000000000..f9c1e39bc --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql_tokenizer.go @@ -0,0 +1,912 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package obfuscate + +import ( + "bytes" + "fmt" + "strings" + "unicode" + "unicode/utf8" +) + +// tokenizer.go implemenents a lexer-like iterator that tokenizes SQL and CQL +// strings, so that an external component can filter or alter each token of the +// string. This implementation can't be used as a real SQL lexer (so a parser +// cannot build the AST) because many rules are ignored to make the tokenizer +// simpler. +// This implementation was inspired by https://github.com/youtube/vitess sql parser +// TODO: add the license to the NOTICE file + +// TokenKind specifies the type of the token being scanned. It may be one of the defined +// constants below or in some cases the actual rune itself. +type TokenKind uint32 + +// EndChar is used to signal that the scanner has finished reading the query. This happens when +// there are no more characters left in the query or when invalid encoding is discovered. EndChar +// is an invalid rune value that can not be found in any valid string. +const EndChar = unicode.MaxRune + 1 + +// list of available tokens; this list has been reduced because we don't +// need a full-fledged tokenizer to implement a Lexer +const ( + LexError = TokenKind(57346) + iota + + ID + Limit + Null + String + DoubleQuotedString + DollarQuotedString // https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING + DollarQuotedFunc // a dollar-quoted string delimited by the tag "$func$"; gets special treatment when feature "dollar_quoted_func" is set + Number + BooleanLiteral + ValueArg + ListArg + Comment + Variable + Savepoint + PreparedStatement + EscapeSequence + NullSafeEqual + LE + GE + NE + Not + As + Alter + Drop + Create + Grant + Revoke + Commit + Begin + Truncate + Select + From + Update + Delete + Insert + Into + Join + TableName + ColonCast + + // PostgreSQL specific JSON operators + JSONSelect // -> + JSONSelectText // ->> + JSONSelectPath // #> + JSONSelectPathText // #>> + JSONContains // @> + JSONContainsLeft // <@ + JSONKeyExists // ? + JSONAnyKeysExist // ?| + JSONAllKeysExist // ?& + JSONDelete // #- + + // FilteredGroupable specifies that the given token has been discarded by one of the + // token filters and that it is groupable together with consecutive FilteredGroupable + // tokens. + FilteredGroupable + + // FilteredGroupableParenthesis is a parenthesis marked as filtered groupable. It is the + // beginning of either a group of values ('(') or a nested query. We track is as + // a special case for when it may start a nested query as opposed to just another + // value group to be obfuscated. + FilteredGroupableParenthesis + + // Filtered specifies that the token is a comma and was discarded by one + // of the filters. + Filtered + + // FilteredBracketedIdentifier specifies that we are currently discarding + // a bracketed identifier (MSSQL). + // See issue https://github.com/DataDog/datadog-trace-agent/issues/475. + FilteredBracketedIdentifier +) + +var tokenKindStrings = map[TokenKind]string{ + LexError: "LexError", + ID: "ID", + Limit: "Limit", + Null: "Null", + String: "String", + DoubleQuotedString: "DoubleQuotedString", + DollarQuotedString: "DollarQuotedString", + DollarQuotedFunc: "DollarQuotedFunc", + Number: "Number", + BooleanLiteral: "BooleanLiteral", + ValueArg: "ValueArg", + ListArg: "ListArg", + Comment: "Comment", + Variable: "Variable", + Savepoint: "Savepoint", + PreparedStatement: "PreparedStatement", + EscapeSequence: "EscapeSequence", + NullSafeEqual: "NullSafeEqual", + LE: "LE", + GE: "GE", + NE: "NE", + Not: "NOT", + As: "As", + Alter: "Alter", + Drop: "Drop", + Create: "Create", + Grant: "Grant", + Revoke: "Revoke", + Commit: "Commit", + Begin: "Begin", + Truncate: "Truncate", + Select: "Select", + From: "From", + Update: "Update", + Delete: "Delete", + Insert: "Insert", + Into: "Into", + Join: "Join", + TableName: "TableName", + ColonCast: "ColonCast", + FilteredGroupable: "FilteredGroupable", + FilteredGroupableParenthesis: "FilteredGroupableParenthesis", + Filtered: "Filtered", + FilteredBracketedIdentifier: "FilteredBracketedIdentifier", + JSONSelect: "JSONSelect", + JSONSelectText: "JSONSelectText", + JSONSelectPath: "JSONSelectPath", + JSONSelectPathText: "JSONSelectPathText", + JSONContains: "JSONContains", + JSONContainsLeft: "JSONContainsLeft", + JSONKeyExists: "JSONKeyExists", + JSONAnyKeysExist: "JSONAnyKeysExist", + JSONAllKeysExist: "JSONAllKeysExist", + JSONDelete: "JSONDelete", +} + +func (k TokenKind) String() string { + str, ok := tokenKindStrings[k] + if !ok { + return "" + } + return str +} + +const ( + // DBMSSQLServer is a MS SQL Server + DBMSSQLServer = "mssql" + // DBMSPostgres is a PostgreSQL Server + DBMSPostgres = "postgresql" +) + +const escapeCharacter = '\\' + +// SQLTokenizer is the struct used to generate SQL +// tokens for the parser. +type SQLTokenizer struct { + pos int // byte offset of lastChar + lastChar rune // last read rune + buf []byte // buf holds the query that we are parsing + off int // off is the index into buf where the unread portion of the query begins. + err error // any error occurred while reading + + curlys uint32 // number of active open curly braces in top-level SQL escape sequences. + + literalEscapes bool // indicates we should not treat backslashes as escape characters + seenEscape bool // indicates whether this tokenizer has seen an escape character within a string + + cfg *SQLConfig +} + +// NewSQLTokenizer creates a new SQLTokenizer for the given SQL string. The literalEscapes argument specifies +// whether escape characters should be treated literally or as such. +func NewSQLTokenizer(sql string, literalEscapes bool, cfg *SQLConfig) *SQLTokenizer { + if cfg == nil { + cfg = new(SQLConfig) + } + return &SQLTokenizer{ + buf: []byte(sql), + cfg: cfg, + literalEscapes: literalEscapes, + } +} + +// Reset the underlying buffer and positions +func (tkn *SQLTokenizer) Reset(in string) { + tkn.pos = 0 + tkn.lastChar = 0 + tkn.buf = []byte(in) + tkn.off = 0 + tkn.err = nil +} + +// keywords used to recognize string tokens +var keywords = map[string]TokenKind{ + "NULL": Null, + "TRUE": BooleanLiteral, + "FALSE": BooleanLiteral, + "SAVEPOINT": Savepoint, + "LIMIT": Limit, + "AS": As, + "ALTER": Alter, + "CREATE": Create, + "GRANT": Grant, + "REVOKE": Revoke, + "COMMIT": Commit, + "BEGIN": Begin, + "TRUNCATE": Truncate, + "DROP": Drop, + "SELECT": Select, + "FROM": From, + "UPDATE": Update, + "DELETE": Delete, + "INSERT": Insert, + "INTO": Into, + "JOIN": Join, +} + +// Err returns the last error that the tokenizer encountered, or nil. +func (tkn *SQLTokenizer) Err() error { return tkn.err } + +func (tkn *SQLTokenizer) setErr(format string, args ...interface{}) { + if tkn.err != nil { + return + } + tkn.err = fmt.Errorf("at position %d: %v", tkn.pos, fmt.Errorf(format, args...)) +} + +// SeenEscape returns whether or not this tokenizer has seen an escape character within a scanned string +func (tkn *SQLTokenizer) SeenEscape() bool { return tkn.seenEscape } + +// Scan scans the tokenizer for the next token and returns +// the token type and the token buffer. +func (tkn *SQLTokenizer) Scan() (TokenKind, []byte) { + if tkn.lastChar == 0 { + tkn.advance() + } + tkn.SkipBlank() + + switch ch := tkn.lastChar; { + case isLeadingLetter(ch) && + !(tkn.cfg.DBMS == DBMSPostgres && ch == '@'): + // The '@' symbol should not be considered part of an identifier in + // postgres, so we skip this in the case where the DBMS is postgres + // and ch is '@'. + return tkn.scanIdentifier() + case isDigit(ch): + return tkn.scanNumber(false) + default: + tkn.advance() + if tkn.lastChar == EndChar && tkn.err != nil { + // advance discovered an invalid encoding. We should return early. + return LexError, nil + } + switch ch { + case EndChar: + if tkn.err != nil { + return LexError, nil + } + return EndChar, nil + case ':': + if tkn.lastChar == ':' { + tkn.advance() + return ColonCast, []byte("::") + } + if unicode.IsSpace(tkn.lastChar) { + // example scenario: "autovacuum: VACUUM ANALYZE fake.table" + return TokenKind(ch), tkn.bytes() + } + if tkn.lastChar != '=' { + return tkn.scanBindVar() + } + fallthrough + case '~': + switch tkn.lastChar { + case '*': + tkn.advance() + return TokenKind('~'), []byte("~*") + default: + return TokenKind(ch), tkn.bytes() + } + case '?': + if tkn.cfg.DBMS == DBMSPostgres { + switch tkn.lastChar { + case '|': + tkn.advance() + return JSONAnyKeysExist, []byte("?|") + case '&': + tkn.advance() + return JSONAllKeysExist, []byte("?&") + default: + return JSONKeyExists, tkn.bytes() + } + } + fallthrough + case '=', ',', ';', '(', ')', '+', '*', '&', '|', '^', ']': + return TokenKind(ch), tkn.bytes() + case '[': + if tkn.cfg.DBMS == DBMSSQLServer { + return tkn.scanString(']', DoubleQuotedString) + } + return TokenKind(ch), tkn.bytes() + case '.': + if isDigit(tkn.lastChar) { + return tkn.scanNumber(true) + } + return TokenKind(ch), tkn.bytes() + case '/': + switch tkn.lastChar { + case '/': + tkn.advance() + return tkn.scanCommentType1("//") + case '*': + tkn.advance() + return tkn.scanCommentType2() + default: + return TokenKind(ch), tkn.bytes() + } + case '-': + switch { + case tkn.lastChar == '-': + tkn.advance() + return tkn.scanCommentType1("--") + case tkn.lastChar == '>': + if tkn.cfg.DBMS == DBMSPostgres { + tkn.advance() + switch tkn.lastChar { + case '>': + tkn.advance() + return JSONSelectText, []byte("->>") + default: + return JSONSelect, []byte("->") + } + } + fallthrough + case isDigit(tkn.lastChar): + return tkn.scanNumber(false) + case tkn.lastChar == '.': + tkn.advance() + if isDigit(tkn.lastChar) { + return tkn.scanNumber(true) + } + tkn.lastChar = '.' + tkn.pos-- + fallthrough + default: + return TokenKind(ch), tkn.bytes() + } + case '#': + switch tkn.cfg.DBMS { + case DBMSSQLServer: + return tkn.scanIdentifier() + case DBMSPostgres: + switch tkn.lastChar { + case '>': + tkn.advance() + switch tkn.lastChar { + case '>': + tkn.advance() + return JSONSelectPathText, []byte("#>>") + default: + return JSONSelectPath, []byte("#>") + } + case '-': + tkn.advance() + return JSONDelete, []byte("#-") + default: + return TokenKind(ch), tkn.bytes() + } + default: + tkn.advance() + return tkn.scanCommentType1("#") + } + case '<': + switch tkn.lastChar { + case '>': + tkn.advance() + return NE, []byte("<>") + case '=': + tkn.advance() + switch tkn.lastChar { + case '>': + tkn.advance() + return NullSafeEqual, []byte("<=>") + default: + return LE, []byte("<=") + } + case '@': + if tkn.cfg.DBMS == DBMSPostgres { + // check for JSONContainsLeft (<@) + tkn.advance() + return JSONContainsLeft, []byte("<@") + } + fallthrough + default: + return TokenKind(ch), tkn.bytes() + } + case '>': + if tkn.lastChar == '=' { + tkn.advance() + return GE, []byte(">=") + } + return TokenKind(ch), tkn.bytes() + case '!': + switch tkn.lastChar { + case '=': + tkn.advance() + return NE, []byte("!=") + case '~': + tkn.advance() + switch tkn.lastChar { + case '*': + tkn.advance() + return NE, []byte("!~*") + default: + return NE, []byte("!~") + } + default: + if isValidCharAfterOperator(tkn.lastChar) { + return Not, tkn.bytes() + } + tkn.setErr(`unexpected char "%c" (%d) after "!"`, tkn.lastChar, tkn.lastChar) + return LexError, tkn.bytes() + } + case '\'': + return tkn.scanString(ch, String) + case '"': + return tkn.scanString(ch, DoubleQuotedString) + case '`': + return tkn.scanString(ch, ID) + case '%': + if tkn.lastChar == '(' { + return tkn.scanVariableIdentifier('%') + } + if isLetter(tkn.lastChar) { + // format parameter (e.g. '%s') + return tkn.scanFormatParameter('%') + } + // modulo operator (e.g. 'id % 8') + return TokenKind(ch), tkn.bytes() + case '$': + if isDigit(tkn.lastChar) { + // TODO(gbbr): the first digit after $ does not necessarily guarantee + // that this isn't a dollar-quoted string constant. We might eventually + // want to cover for this use-case too (e.g. $1$some text$1$). + return tkn.scanPreparedStatement('$') + } + kind, tok := tkn.scanDollarQuotedString() + if kind == DollarQuotedFunc { + // this is considered an embedded query, we should try and + // obfuscate it + out, err := attemptObfuscation(NewSQLTokenizer(string(tok), tkn.literalEscapes, tkn.cfg)) + if err != nil { + // if we can't obfuscate it, treat it as a regular string + return DollarQuotedString, tok + } + tok = append(append([]byte("$func$"), []byte(out.Query)...), []byte("$func$")...) + } + return kind, tok + case '@': + if tkn.cfg.DBMS == DBMSPostgres { + // For postgres the @ symbol is reserved as an operator + // https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-OPERATORS + // And is used as a json operator + // https://www.postgresql.org/docs/9.5/functions-json.html + switch tkn.lastChar { + case '>': + tkn.advance() + return JSONContains, []byte("@>") + default: + return TokenKind(ch), tkn.bytes() + } + } + fallthrough + case '{': + if tkn.pos == 1 || tkn.curlys > 0 { + // Do not fully obfuscate top-level SQL escape sequences like {{[?=]call procedure-name[([parameter][,parameter]...)]}. + // We want these to display a bit more context than just a plain '?' + // See: https://docs.oracle.com/cd/E13157_01/wlevs/docs30/jdbc_drivers/sqlescape.html + tkn.curlys++ + return TokenKind(ch), tkn.bytes() + } + return tkn.scanEscapeSequence('{') + case '}': + if tkn.curlys == 0 { + // A closing curly brace has no place outside an in-progress top-level SQL escape sequence + // started by the '{' switch-case. + tkn.setErr(`unexpected byte %d`, ch) + return LexError, tkn.bytes() + } + tkn.curlys-- + return TokenKind(ch), tkn.bytes() + default: + tkn.setErr(`unexpected byte %d`, ch) + return LexError, tkn.bytes() + } + } +} + +// SkipBlank moves the tokenizer forward until hitting a non-whitespace character +// The whitespace definition used here is the same as unicode.IsSpace +func (tkn *SQLTokenizer) SkipBlank() { + for unicode.IsSpace(tkn.lastChar) { + tkn.advance() + } + tkn.bytes() +} + +// toUpper is a modified version of bytes.ToUpper. It returns an upper-cased version of the byte +// slice src with all Unicode letters mapped to their upper case. It is modified to also accept a +// byte slice dst as an argument, the underlying storage of which (up to the capacity of dst) +// will be used as the destination of the upper-case copy of src, if it fits. As a special case, +// toUpper will return src if the byte slice is already upper-case. This function is used rather +// than bytes.ToUpper to improve the memory performance of the obfuscator by saving unnecessary +// allocations happening in bytes.ToUpper +func toUpper(src, dst []byte) []byte { + dst = dst[:0] + isASCII, hasLower := true, false + for i := 0; i < len(src); i++ { + c := src[i] + if c >= utf8.RuneSelf { + isASCII = false + break + } + hasLower = hasLower || ('a' <= c && c <= 'z') + } + if cap(dst) < len(src) { + dst = make([]byte, 0, len(src)) + } + if isASCII { // optimize for ASCII-only byte slices. + if !hasLower { + // Just return src. + return src + } + dst = dst[:len(src)] + for i := 0; i < len(src); i++ { + c := src[i] + if 'a' <= c && c <= 'z' { + c -= 'a' - 'A' + } + dst[i] = c + } + return dst + } + // This *could* be optimized, but it's an uncommon case. + return bytes.Map(unicode.ToUpper, src) +} + +func (tkn *SQLTokenizer) scanIdentifier() (TokenKind, []byte) { + tkn.advance() + for isLetter(tkn.lastChar) || isDigit(tkn.lastChar) || strings.ContainsRune(".*$", tkn.lastChar) { + tkn.advance() + } + + t := tkn.bytes() + // Space allows us to upper-case identifiers 256 bytes long or less without allocating heap + // storage for them, since space is allocated on the stack. A size of 256 bytes was chosen + // based on the allowed length of sql identifiers in various sql implementations. + var space [256]byte + upper := toUpper(t, space[:0]) + if keywordID, found := keywords[string(upper)]; found { + return keywordID, t + } + return ID, t +} + +func (tkn *SQLTokenizer) scanVariableIdentifier(prefix rune) (TokenKind, []byte) { + for tkn.advance(); tkn.lastChar != ')' && tkn.lastChar != EndChar; tkn.advance() { + } + tkn.advance() + if !isLetter(tkn.lastChar) { + tkn.setErr(`invalid character after variable identifier: "%c" (%d)`, tkn.lastChar, tkn.lastChar) + return LexError, tkn.bytes() + } + tkn.advance() + return Variable, tkn.bytes() +} + +func (tkn *SQLTokenizer) scanFormatParameter(prefix rune) (TokenKind, []byte) { + tkn.advance() + return Variable, tkn.bytes() +} + +// scanDollarQuotedString scans a Postgres dollar-quoted string constant. +// See: https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING +func (tkn *SQLTokenizer) scanDollarQuotedString() (TokenKind, []byte) { + kind, tag := tkn.scanString('$', String) + if kind == LexError { + return kind, tkn.bytes() + } + var ( + got int + buf bytes.Buffer + ) + delim := tag + // on empty strings, tkn.scanString returns the delimiters + if string(delim) != "$$" { + // on non-empty strings, the delimiter is $tag$ + delim = append([]byte{'$'}, delim...) + delim = append(delim, '$') + } + for { + ch := tkn.lastChar + tkn.advance() + if ch == EndChar { + tkn.setErr("unexpected EOF in dollar-quoted string") + return LexError, buf.Bytes() + } + if byte(ch) == delim[got] { + got++ + if got == len(delim) { + break + } + continue + } + if got > 0 { + _, err := buf.Write(delim[:got]) + if err != nil { + tkn.setErr("error reading dollar-quoted string: %v", err) + return LexError, buf.Bytes() + } + got = 0 + } + buf.WriteRune(ch) + } + if tkn.cfg.DollarQuotedFunc && string(delim) == "$func$" { + return DollarQuotedFunc, buf.Bytes() + } + return DollarQuotedString, buf.Bytes() +} + +func (tkn *SQLTokenizer) scanPreparedStatement(prefix rune) (TokenKind, []byte) { + // a prepared statement expect a digit identifier like $1 + if !isDigit(tkn.lastChar) { + tkn.setErr(`prepared statements must start with digits, got "%c" (%d)`, tkn.lastChar, tkn.lastChar) + return LexError, tkn.bytes() + } + + // scanNumber keeps the prefix rune intact. + // read numbers and return an error if any + token, buff := tkn.scanNumber(false) + if token == LexError { + tkn.setErr("invalid number") + return LexError, tkn.bytes() + } + return PreparedStatement, buff +} + +func (tkn *SQLTokenizer) scanEscapeSequence(braces rune) (TokenKind, []byte) { + for tkn.lastChar != '}' && tkn.lastChar != EndChar { + tkn.advance() + } + + // we've reached the end of the string without finding + // the closing curly braces + if tkn.lastChar == EndChar { + tkn.setErr("unexpected EOF in escape sequence") + return LexError, tkn.bytes() + } + + tkn.advance() + return EscapeSequence, tkn.bytes() +} + +func (tkn *SQLTokenizer) scanBindVar() (TokenKind, []byte) { + token := ValueArg + if tkn.lastChar == ':' { + token = ListArg + tkn.advance() + } + if !isLetter(tkn.lastChar) && !isDigit(tkn.lastChar) { + tkn.setErr(`bind variables should start with letters or digits, got "%c" (%d)`, tkn.lastChar, tkn.lastChar) + return LexError, tkn.bytes() + } + for isLetter(tkn.lastChar) || isDigit(tkn.lastChar) || tkn.lastChar == '.' { + tkn.advance() + } + return token, tkn.bytes() +} + +func (tkn *SQLTokenizer) scanMantissa(base int) { + for digitVal(tkn.lastChar) < base { + tkn.advance() + } +} + +func (tkn *SQLTokenizer) scanNumber(seenDecimalPoint bool) (TokenKind, []byte) { + if seenDecimalPoint { + tkn.scanMantissa(10) + goto exponent + } + + if tkn.lastChar == '0' { + // int or float + tkn.advance() + if tkn.lastChar == 'x' || tkn.lastChar == 'X' { + // hexadecimal int + tkn.advance() + tkn.scanMantissa(16) + } else { + // octal int or float + tkn.scanMantissa(8) + if tkn.lastChar == '8' || tkn.lastChar == '9' { + tkn.scanMantissa(10) + } + if tkn.lastChar == '.' || tkn.lastChar == 'e' || tkn.lastChar == 'E' { + goto fraction + } + } + goto exit + } + + // decimal int or float + tkn.scanMantissa(10) + +fraction: + if tkn.lastChar == '.' { + tkn.advance() + tkn.scanMantissa(10) + } + +exponent: + if tkn.lastChar == 'e' || tkn.lastChar == 'E' { + tkn.advance() + if tkn.lastChar == '+' || tkn.lastChar == '-' { + tkn.advance() + } + tkn.scanMantissa(10) + } + +exit: + t := tkn.bytes() + if len(t) == 0 { + tkn.setErr("Parse error: ended up with zero-length number.") + return LexError, nil + } + return Number, t +} + +func (tkn *SQLTokenizer) scanString(delim rune, kind TokenKind) (TokenKind, []byte) { + buf := bytes.NewBuffer(tkn.buf[:0]) + for { + ch := tkn.lastChar + tkn.advance() + if ch == delim { + if tkn.lastChar == delim { + // doubling a delimiter is the default way to embed the delimiter within a string + tkn.advance() + } else { + // a single delimiter denotes the end of the string + break + } + } else if ch == escapeCharacter { + tkn.seenEscape = true + + if !tkn.literalEscapes { + // treat as an escape character + ch = tkn.lastChar + tkn.advance() + } + } + if ch == EndChar { + tkn.setErr("unexpected EOF in string") + return LexError, buf.Bytes() + } + buf.WriteRune(ch) + } + if kind == ID && buf.Len() == 0 || bytes.IndexFunc(buf.Bytes(), func(r rune) bool { return !unicode.IsSpace(r) }) == -1 { + // This string is an empty or white-space only identifier. + // We should keep the start and end delimiters in order to + // avoid creating invalid queries. + // See: https://github.com/DataDog/datadog-trace-agent/issues/316 + return kind, append(runeBytes(delim), runeBytes(delim)...) + } + return kind, buf.Bytes() +} + +func (tkn *SQLTokenizer) scanCommentType1(prefix string) (TokenKind, []byte) { + for tkn.lastChar != EndChar { + if tkn.lastChar == '\n' { + tkn.advance() + break + } + tkn.advance() + } + return Comment, tkn.bytes() +} + +func (tkn *SQLTokenizer) scanCommentType2() (TokenKind, []byte) { + for { + if tkn.lastChar == '*' { + tkn.advance() + if tkn.lastChar == '/' { + tkn.advance() + break + } + continue + } + if tkn.lastChar == EndChar { + tkn.setErr("unexpected EOF in comment") + return LexError, tkn.bytes() + } + tkn.advance() + } + return Comment, tkn.bytes() +} + +// advance advances the tokenizer to the next rune. If the decoder encounters an error decoding, or +// the end of the buffer is reached, tkn.lastChar will be set to EndChar. In case of a decoding +// error, tkn.err will also be set. +func (tkn *SQLTokenizer) advance() { + ch, n := utf8.DecodeRune(tkn.buf[tkn.off:]) + if ch == utf8.RuneError && n < 2 { + tkn.pos++ + tkn.lastChar = EndChar + if n == 1 { + tkn.setErr("invalid UTF-8 encoding beginning with 0x%x", tkn.buf[tkn.off]) + } + return + } + if tkn.lastChar != 0 || tkn.pos > 0 { + // we are past the first character + tkn.pos += n + } + tkn.off += n + tkn.lastChar = ch +} + +// bytes returns all the bytes that were advanced over since its last call. +// This excludes tkn.lastChar, which will remain in the buffer +func (tkn *SQLTokenizer) bytes() []byte { + if tkn.lastChar == EndChar { + ret := tkn.buf[:tkn.off] + tkn.buf = tkn.buf[tkn.off:] + tkn.off = 0 + return ret + } + lastLen := utf8.RuneLen(tkn.lastChar) + ret := tkn.buf[:tkn.off-lastLen] + tkn.buf = tkn.buf[tkn.off-lastLen:] + tkn.off = lastLen + return ret +} + +// Position exports the tokenizer's current position in the query +func (tkn *SQLTokenizer) Position() int { + return tkn.pos +} + +func isLeadingLetter(ch rune) bool { + return unicode.IsLetter(ch) || ch == '_' || ch == '@' +} + +func isLetter(ch rune) bool { + return isLeadingLetter(ch) || ch == '#' +} + +func digitVal(ch rune) int { + switch { + case '0' <= ch && ch <= '9': + return int(ch) - '0' + case 'a' <= ch && ch <= 'f': + return int(ch) - 'a' + 10 + case 'A' <= ch && ch <= 'F': + return int(ch) - 'A' + 10 + } + return 16 // larger than any legal digit val +} + +func isDigit(ch rune) bool { return '0' <= ch && ch <= '9' } + +// runeBytes converts the given rune to a slice of bytes. +func runeBytes(r rune) []byte { + buf := make([]byte, utf8.UTFMax) + n := utf8.EncodeRune(buf, r) + return buf[:n] +} + +// isValidCharAfterOperator returns true if c is a valid character after an operator +func isValidCharAfterOperator(c rune) bool { + return c == '(' || c == '`' || c == '\'' || c == '"' || c == '+' || c == '-' || unicode.IsSpace(c) || isLetter(c) || isDigit(c) +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/LICENSE b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/LICENSE new file mode 100644 index 000000000..b370545be --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/LICENSE @@ -0,0 +1,200 @@ + 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 2016-present Datadog, Inc. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/README.md b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/README.md new file mode 100644 index 000000000..a42ffb54e --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/README.md @@ -0,0 +1,5 @@ +# Remote Config Go client + +This package powers the Remote Config client shipped in the Go tracer and in all the agent processes (core-agent, trace-agent, system-probe, ...). + +To add a new product simply add it to `products.go` as a constant and in the `validProducts` set. diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/agent_config.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/agent_config.go new file mode 100644 index 000000000..f6df6a937 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/agent_config.go @@ -0,0 +1,159 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2023-present Datadog, Inc. + +package state + +import ( + "encoding/json" + "fmt" + "regexp" + + "github.com/pkg/errors" +) + +const agentConfigOrderID = "configuration_order" + +var datadogConfigIDRegexp = regexp.MustCompile(`^datadog/\d+/AGENT_CONFIG/([^/]+)/[^/]+$`) + +// AgentConfig is a deserialized agent configuration file +// along with the associated metadata +type AgentConfig struct { + Config agentConfigData + Metadata Metadata +} + +// ConfigContent contains the configurations set by remote-config +type ConfigContent struct { + LogLevel string `json:"log_level"` +} + +type agentConfigData struct { + Name string `json:"name"` + Config ConfigContent `json:"config"` +} + +// AgentConfigOrder is a deserialized agent configuration file +// along with the associated metadata +type AgentConfigOrder struct { + Config agentConfigOrderData + Metadata Metadata +} + +type agentConfigOrderData struct { + Order []string `json:"order"` + InternalOrder []string `json:"internal_order"` +} + +// AgentConfigState contains the state of the config in case of fallback or override +type AgentConfigState struct { + FallbackLogLevel string + LatestLogLevel string +} + +// parseConfigAgentConfig parses an agent task config +func parseConfigAgentConfig(data []byte, metadata Metadata) (AgentConfig, error) { + var d agentConfigData + + err := json.Unmarshal(data, &d) + if err != nil { + return AgentConfig{}, fmt.Errorf("Unexpected AGENT_CONFIG received through remote-config: %s", err) + } + + return AgentConfig{ + Config: d, + Metadata: metadata, + }, nil +} + +// parseConfigAgentConfig parses an agent task config +func parseConfigAgentConfigOrder(data []byte, metadata Metadata) (AgentConfigOrder, error) { + var d agentConfigOrderData + + err := json.Unmarshal(data, &d) + if err != nil { + return AgentConfigOrder{}, fmt.Errorf("Unexpected AGENT_CONFIG received through remote-config: %s", err) + } + + return AgentConfigOrder{ + Config: d, + Metadata: metadata, + }, nil +} + +// MergeRCAgentConfig is the callback function called when there is an AGENT_CONFIG config update +// The RCClient can directly call back listeners, because there would be no way to send back +// RCTE2 configuration applied state to RC backend. +func MergeRCAgentConfig(applyStatus func(cfgPath string, status ApplyStatus), updates map[string]RawConfig) (ConfigContent, error) { + var orderFile AgentConfigOrder + var hasError bool + var fullErr error + parsedLayers := map[string]AgentConfig{} + + for configPath, c := range updates { + var err error + matched := datadogConfigIDRegexp.FindStringSubmatch(configPath) + if len(matched) != 2 { + err = fmt.Errorf("config file path '%s' has wrong format", configPath) + hasError = true + fullErr = errors.Wrap(fullErr, err.Error()) + applyStatus(configPath, ApplyStatus{ + State: ApplyStateError, + Error: err.Error(), + }) + // If a layer is wrong, fail later to parse the rest and check them all + continue + } + + parsedConfigID := matched[1] + + // Ignore the configuration order file + if parsedConfigID == agentConfigOrderID { + orderFile, err = parseConfigAgentConfigOrder(c.Config, c.Metadata) + if err != nil { + hasError = true + fullErr = errors.Wrap(fullErr, err.Error()) + applyStatus(configPath, ApplyStatus{ + State: ApplyStateError, + Error: err.Error(), + }) + // If a layer is wrong, fail later to parse the rest and check them all + continue + } + } else { + cfg, err := parseConfigAgentConfig(c.Config, c.Metadata) + if err != nil { + hasError = true + applyStatus(configPath, ApplyStatus{ + State: ApplyStateError, + Error: err.Error(), + }) + // If a layer is wrong, fail later to parse the rest and check them all + continue + } + parsedLayers[parsedConfigID] = cfg + } + } + + // If there was at least one error, don't apply any config + if hasError || (len(orderFile.Config.Order) == 0 && len(orderFile.Config.InternalOrder) == 0) { + return ConfigContent{}, fullErr + } + + // Go through all the layers that were sent, and apply them one by one to the merged structure + mergedConfig := ConfigContent{} + for i := len(orderFile.Config.Order) - 1; i >= 0; i-- { + if layer, found := parsedLayers[orderFile.Config.Order[i]]; found { + mergedConfig.LogLevel = layer.Config.Config.LogLevel + } + } + // Same for internal config + for i := len(orderFile.Config.InternalOrder) - 1; i >= 0; i-- { + if layer, found := parsedLayers[orderFile.Config.InternalOrder[i]]; found { + mergedConfig.LogLevel = layer.Config.Config.LogLevel + } + } + + return mergedConfig, nil +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs.go new file mode 100644 index 000000000..06fdb2730 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs.go @@ -0,0 +1,123 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2022-present Datadog, Inc. + +package state + +import ( + "encoding/json" + "errors" + "fmt" + + "github.com/DataDog/go-tuf/data" +) + +// ErrNoConfigVersion occurs when a target file's custom meta is missing the config version +var ErrNoConfigVersion = errors.New("version missing in custom file meta") + +func parseConfig(product string, raw []byte, metadata Metadata) (interface{}, error) { + if _, validProduct := validProducts[product]; !validProduct { + return nil, fmt.Errorf("unknown product: %s", product) + } + + switch product { + // ASM products are parsed directly in this client + case ProductASMFeatures: + return parseASMFeaturesConfig(raw, metadata) + case ProductASMDD: + return parseConfigASMDD(raw, metadata) + case ProductASMData: + return parseConfigASMData(raw, metadata) + // case ProductAgentTask: + // return ParseConfigAgentTask(raw, metadata) + // Other products are parsed separately + default: + return RawConfig{ + Config: raw, + Metadata: metadata, + }, nil + } +} + +// RawConfig holds a config that will be parsed separately +type RawConfig struct { + Config []byte + Metadata Metadata +} + +// GetConfigs returns the current configs of a given product +func (r *Repository) GetConfigs(product string) map[string]RawConfig { + typedConfigs := make(map[string]RawConfig) + configs := r.getConfigs(product) + + for path, conf := range configs { + // We control this, so if this has gone wrong something has gone horribly wrong + typed, ok := conf.(RawConfig) + if !ok { + panic("unexpected config stored as RawConfig") + } + + typedConfigs[path] = typed + } + + return typedConfigs +} + +// Metadata stores remote config metadata for a given configuration +type Metadata struct { + Product string + ID string + Name string + Version uint64 + RawLength uint64 + Hashes map[string][]byte + ApplyStatus ApplyStatus +} + +func newConfigMetadata(parsedPath configPath, tfm data.TargetFileMeta) (Metadata, error) { + var m Metadata + m.ID = parsedPath.ConfigID + m.Product = parsedPath.Product + m.Name = parsedPath.Name + m.RawLength = uint64(tfm.Length) + m.Hashes = make(map[string][]byte) + for k, v := range tfm.Hashes { + m.Hashes[k] = []byte(v) + } + v, err := fileMetaVersion(tfm) + if err != nil { + return Metadata{}, err + } + m.Version = v + + return m, nil +} + +type fileMetaCustom struct { + Version *uint64 `json:"v"` +} + +func fileMetaVersion(fm data.TargetFileMeta) (uint64, error) { + if fm.Custom == nil { + return 0, ErrNoConfigVersion + } + fmc, err := parseFileMetaCustom(*fm.Custom) + if err != nil { + return 0, err + } + + return *fmc.Version, nil +} + +func parseFileMetaCustom(rawCustom []byte) (fileMetaCustom, error) { + var custom fileMetaCustom + err := json.Unmarshal(rawCustom, &custom) + if err != nil { + return fileMetaCustom{}, err + } + if custom.Version == nil { + return fileMetaCustom{}, ErrNoConfigVersion + } + return custom, nil +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_agent_task.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_agent_task.go new file mode 100644 index 000000000..618bf7335 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_agent_task.go @@ -0,0 +1,59 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2023-present Datadog, Inc. + +package state + +import ( + "encoding/json" + "fmt" +) + +// AgentTaskConfig is a deserialized agent task configuration file +// along with the associated metadata +type AgentTaskConfig struct { + Config AgentTaskData + Metadata Metadata +} + +// AgentTaskData is the content of a agent task configuration file +type AgentTaskData struct { + TaskType string `json:"task_type"` + UUID string `json:"uuid"` + TaskArgs map[string]string `json:"args"` +} + +// ParseConfigAgentTask parses an agent task config +func ParseConfigAgentTask(data []byte, metadata Metadata) (AgentTaskConfig, error) { + var d AgentTaskData + + err := json.Unmarshal(data, &d) + if err != nil { + return AgentTaskConfig{}, fmt.Errorf("Unexpected AGENT_TASK received through remote-config: %s", err) + } + + return AgentTaskConfig{ + Config: d, + Metadata: metadata, + }, nil +} + +// AgentTaskConfigs returns the currently active AGENT_TASK configs +func (r *Repository) AgentTaskConfigs() map[string]AgentTaskConfig { + typedConfigs := make(map[string]AgentTaskConfig) + + configs := r.getConfigs(ProductAgentTask) + + for path, conf := range configs { + // We control this, so if this has gone wrong something has gone horribly wrong + typed, ok := conf.(AgentTaskConfig) + if !ok { + panic("unexpected config stored as AgentTaskConfigs") + } + + typedConfigs[path] = typed + } + + return typedConfigs +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_asm.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_asm.go new file mode 100644 index 000000000..ac7a918e8 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_asm.go @@ -0,0 +1,159 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2022-present Datadog, Inc. + +package state + +import ( + "encoding/json" +) + +// ConfigASMDD is a deserialized ASM DD configuration file along with its +// associated remote config metadata +type ConfigASMDD struct { + Config []byte + Metadata Metadata +} + +func parseConfigASMDD(data []byte, metadata Metadata) (ConfigASMDD, error) { + return ConfigASMDD{ + Config: data, + Metadata: metadata, + }, nil +} + +// ASMDDConfigs returns the currently active ASMDD configs +func (r *Repository) ASMDDConfigs() map[string]ConfigASMDD { + typedConfigs := make(map[string]ConfigASMDD) + + configs := r.getConfigs(ProductASMDD) + + for path, conf := range configs { + // We control this, so if this has gone wrong something has gone horribly wrong + typed, ok := conf.(ConfigASMDD) + if !ok { + panic("unexpected config stored as ASMDD Config") + } + + typedConfigs[path] = typed + } + + return typedConfigs +} + +// ASMFeaturesConfig is a deserialized configuration file that indicates whether ASM should be enabled +// within a tracer, along with its associated remote config metadata. +type ASMFeaturesConfig struct { + Config ASMFeaturesData + Metadata Metadata +} + +// ASMFeaturesData describes the enabled state of ASM features +type ASMFeaturesData struct { + ASM struct { + Enabled bool `json:"enabled"` + } `json:"asm"` +} + +func parseASMFeaturesConfig(data []byte, metadata Metadata) (ASMFeaturesConfig, error) { + var f ASMFeaturesData + + err := json.Unmarshal(data, &f) + if err != nil { + return ASMFeaturesConfig{}, nil + } + + return ASMFeaturesConfig{ + Config: f, + Metadata: metadata, + }, nil +} + +// ASMFeaturesConfigs returns the currently active ASMFeatures configs +func (r *Repository) ASMFeaturesConfigs() map[string]ASMFeaturesConfig { + typedConfigs := make(map[string]ASMFeaturesConfig) + + configs := r.getConfigs(ProductASMFeatures) + + for path, conf := range configs { + // We control this, so if this has gone wrong something has gone horribly wrong + typed, ok := conf.(ASMFeaturesConfig) + if !ok { + panic("unexpected config stored as ASMFeaturesConfig") + } + + typedConfigs[path] = typed + } + + return typedConfigs +} + +// ApplyState represents the status of a configuration application by a remote configuration client +// Clients need to either ack the correct application of received configurations, or communicate that +// they haven't applied it yet, or communicate any error that may have happened while doing so +type ApplyState uint64 + +const ( + ApplyStateUnknown ApplyState = iota + ApplyStateUnacknowledged + ApplyStateAcknowledged + ApplyStateError +) + +// ApplyStatus is the processing status for a given configuration. +// It basically represents whether a config was successfully processed and apply, or if an error occurred +type ApplyStatus struct { + State ApplyState + Error string +} + +// ASMDataConfig is a deserialized configuration file that holds rules data that can be used +// by the ASM WAF for specific features (example: ip blocking). +type ASMDataConfig struct { + Config ASMDataRulesData + Metadata Metadata +} + +// ASMDataRulesData is a serializable array of rules data entries +type ASMDataRulesData struct { + RulesData []ASMDataRuleData `json:"rules_data"` +} + +// ASMDataRuleData is an entry in the rules data list held by an ASMData configuration +type ASMDataRuleData struct { + ID string `json:"id"` + Type string `json:"type"` + Data []ASMDataRuleDataEntry `json:"data"` +} + +// ASMDataRuleDataEntry represents a data entry in a rule data file +type ASMDataRuleDataEntry struct { + Expiration int64 `json:"expiration,omitempty"` + Value string `json:"value"` +} + +func parseConfigASMData(data []byte, metadata Metadata) (ASMDataConfig, error) { + cfg := ASMDataConfig{ + Metadata: metadata, + } + err := json.Unmarshal(data, &cfg.Config) + return cfg, err +} + +// ASMDataConfigs returns the currently active ASMData configs +func (r *Repository) ASMDataConfigs() map[string]ASMDataConfig { + typedConfigs := make(map[string]ASMDataConfig) + configs := r.getConfigs(ProductASMData) + + for path, cfg := range configs { + // We control this, so if this has gone wrong something has gone horribly wrong + typed, ok := cfg.(ASMDataConfig) + if !ok { + panic("unexpected config stored as ASMDataConfig") + } + typedConfigs[path] = typed + } + + return typedConfigs +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/path.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/path.go new file mode 100644 index 000000000..d1a4d69e2 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/path.go @@ -0,0 +1,100 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2022-present Datadog, Inc. + +package state + +import ( + "fmt" + "regexp" + "strconv" + "strings" +) + +var ( + // matches datadog//// for datadog//// + datadogPathRegexp = regexp.MustCompile(`^datadog/(\d+)/([^/]+)/([^/]+)/([^/]+)$`) + datadogPathRegexpGroups = 4 + + // matches employee/// for employee//// + employeePathRegexp = regexp.MustCompile(`^employee/([^/]+)/([^/]+)/([^/]+)$`) + employeePathRegexpGroups = 3 +) + +type source uint + +const ( + sourceUnknown source = iota + sourceDatadog + sourceEmployee +) + +type configPath struct { + Source source + OrgID int64 + Product string + ConfigID string + Name string +} + +func parseConfigPath(path string) (configPath, error) { + configType := parseConfigPathSource(path) + switch configType { + case sourceDatadog: + return parseDatadogConfigPath(path) + case sourceEmployee: + return parseEmployeeConfigPath(path) + } + return configPath{}, fmt.Errorf("config path '%s' has unknown source", path) +} + +func parseDatadogConfigPath(path string) (configPath, error) { + matchedGroups := datadogPathRegexp.FindStringSubmatch(path) + if len(matchedGroups) != datadogPathRegexpGroups+1 { + return configPath{}, fmt.Errorf("config file path '%s' has wrong format", path) + } + rawOrgID := matchedGroups[1] + orgID, err := strconv.ParseInt(rawOrgID, 10, 64) + if err != nil { + return configPath{}, fmt.Errorf("could not parse orgID '%s' in config file path: %v", rawOrgID, err) + } + rawProduct := matchedGroups[2] + if len(rawProduct) == 0 { + return configPath{}, fmt.Errorf("product is empty") + } + return configPath{ + Source: sourceDatadog, + OrgID: orgID, + Product: rawProduct, + ConfigID: matchedGroups[3], + Name: matchedGroups[4], + }, nil +} + +func parseEmployeeConfigPath(path string) (configPath, error) { + matchedGroups := employeePathRegexp.FindStringSubmatch(path) + if len(matchedGroups) != employeePathRegexpGroups+1 { + return configPath{}, fmt.Errorf("config file path '%s' has wrong format", path) + } + rawProduct := matchedGroups[1] + if len(rawProduct) == 0 { + return configPath{}, fmt.Errorf("product is empty") + } + return configPath{ + Source: sourceEmployee, + Product: rawProduct, + ConfigID: matchedGroups[2], + Name: matchedGroups[3], + }, nil +} + +func parseConfigPathSource(path string) source { + switch { + case strings.HasPrefix(path, "datadog/"): + return sourceDatadog + case strings.HasPrefix(path, "employee/"): + return sourceEmployee + } + return sourceUnknown +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/products.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/products.go new file mode 100644 index 000000000..96f635df6 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/products.go @@ -0,0 +1,45 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2022-present Datadog, Inc. + +package state + +var validProducts = map[string]struct{}{ + ProductAgentConfig: {}, + ProductAgentTask: {}, + ProductAPMSampling: {}, + ProductCWSDD: {}, + ProductCWSCustom: {}, + ProductCWSProfiles: {}, + ProductASM: {}, + ProductASMFeatures: {}, + ProductASMDD: {}, + ProductASMData: {}, + ProductAPMTracing: {}, +} + +const ( + // ProductAgentConfig is to receive agent configurations, like the log level + ProductAgentConfig = "AGENT_CONFIG" + // ProductAgentTask is to receive agent task instruction, like a flare + ProductAgentTask = "AGENT_TASK" + // ProductAPMSampling is the apm sampling product + ProductAPMSampling = "APM_SAMPLING" + // ProductCWSDD is the cloud workload security product managed by datadog employees + ProductCWSDD = "CWS_DD" + // ProductCWSCustom is the cloud workload security product managed by datadog customers + ProductCWSCustom = "CWS_CUSTOM" + // ProductCWSProfiles is the cloud workload security profile product + ProductCWSProfiles = "CWS_SECURITY_PROFILES" + // ProductASM is the ASM product used by customers to issue rules configurations + ProductASM = "ASM" + // ProductASMFeatures is the ASM product used form ASM activation through remote config + ProductASMFeatures = "ASM_FEATURES" + // ProductASMDD is the application security monitoring product managed by datadog employees + ProductASMDD = "ASM_DD" + // ProductASMData is the ASM product used to configure WAF rules data + ProductASMData = "ASM_DATA" + // ProductAPMTracing is the apm tracing product + ProductAPMTracing = "APM_TRACING" +) diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/repository.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/repository.go new file mode 100644 index 000000000..ced2a3db2 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/repository.go @@ -0,0 +1,442 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2022-present Datadog, Inc. + +package state + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "log" + "strings" + + "github.com/DataDog/go-tuf/data" +) + +var ( + // ErrMalformedEmbeddedRoot occurs when the TUF root provided is invalid + ErrMalformedEmbeddedRoot = errors.New("malformed embedded TUF root file provided") +) + +// RepositoryState contains all of the information about the current config files +// stored by the client to be able to make an update request to an Agent +type RepositoryState struct { + Configs []ConfigState + CachedFiles []CachedFile + TargetsVersion int64 + RootsVersion int64 + OpaqueBackendState []byte +} + +// ConfigState describes an applied config by the agent client. +type ConfigState struct { + Product string + ID string + Version uint64 + ApplyStatus ApplyStatus +} + +// CachedFile describes a cached file stored by the agent client +// +// Note: You may be wondering why this exists when `ConfigState` exists +// as well. The API for requesting updates does not mandate that a client +// cache config files. This implementation just happens to do so. +type CachedFile struct { + Path string + Length uint64 + Hashes map[string][]byte +} + +// An Update contains all the data needed to update a client's remote config repository state +type Update struct { + // TUFRoots contains, in order, updated roots that this repository needs to keep up with TUF validation + TUFRoots [][]byte + // TUFTargets is the latest TUF Targets file and is used to validate raw config files + TUFTargets []byte + // TargetFiles stores the raw config files by their full TUF path + TargetFiles map[string][]byte + // ClientcConfigs is a list of TUF path's corresponding to config files designated for this repository + ClientConfigs []string +} + +// isEmpty returns whether or not all the fields of `Update` are empty +func (u *Update) isEmpty() bool { + return len(u.TUFRoots) == 0 && len(u.TUFTargets) == 0 && (u.TargetFiles == nil || len(u.TargetFiles) == 0) && len(u.ClientConfigs) == 0 +} + +// Repository is a remote config client used in a downstream process to retrieve +// remote config updates from an Agent. +type Repository struct { + // TUF related data + latestTargets *data.Targets + tufRootsClient *tufRootsClient + opaqueBackendState []byte + + // Unverified mode + tufVerificationEnabled bool + latestRootVersion int64 + + // Config file storage + metadata map[string]Metadata + configs map[string]map[string]interface{} +} + +// NewRepository creates a new remote config repository that will track +// both TUF metadata and raw config files for a client. +func NewRepository(embeddedRoot []byte) (*Repository, error) { + if embeddedRoot == nil { + return nil, ErrMalformedEmbeddedRoot + } + + configs := make(map[string]map[string]interface{}) + for product := range validProducts { + configs[product] = make(map[string]interface{}) + } + + tufRootsClient, err := newTufRootsClient(embeddedRoot) + if err != nil { + return nil, err + } + + return &Repository{ + latestTargets: data.NewTargets(), + tufRootsClient: tufRootsClient, + metadata: make(map[string]Metadata), + configs: configs, + tufVerificationEnabled: true, + }, nil +} + +// NewUnverifiedRepository creates a new remote config repository that will +// track config files for a client WITHOUT verifying any TUF related metadata. +// +// When creating this we pretend we have a root version of 1, as the backend expects +// to not have to send the initial "embedded" root. +func NewUnverifiedRepository() (*Repository, error) { + configs := make(map[string]map[string]interface{}) + for product := range validProducts { + configs[product] = make(map[string]interface{}) + } + + return &Repository{ + latestTargets: data.NewTargets(), + metadata: make(map[string]Metadata), + configs: configs, + tufVerificationEnabled: false, + latestRootVersion: 1, // The backend expects us to start with a root version of 1. + }, nil +} + +// Update processes the ClientGetConfigsResponse from the Agent and updates the +// configuration state +func (r *Repository) Update(update Update) ([]string, error) { + var err error + var updatedTargets *data.Targets + var tmpRootClient *tufRootsClient + + // If there's literally nothing in the update, it's not an error. + if update.isEmpty() { + return []string{}, nil + } + + // TUF: Update the roots and verify the TUF Targets file (optional) + // + // We don't want to partially update the state, so we need a temporary client to hold the new root + // data until we know it's valid. Since verification is optional, if the repository was configured + // to not do TUF verification we only deserialize the TUF targets file. + if r.tufVerificationEnabled { + tmpRootClient, err = r.tufRootsClient.clone() + if err != nil { + return nil, err + } + err = tmpRootClient.updateRoots(update.TUFRoots) + if err != nil { + return nil, err + } + + updatedTargets, err = tmpRootClient.validateTargets(update.TUFTargets) + if err != nil { + return nil, err + } + } else { + updatedTargets, err = unsafeUnmarshalTargets(update.TUFTargets) + if err != nil { + return nil, err + } + } + + clientConfigsMap := make(map[string]struct{}) + for _, f := range update.ClientConfigs { + clientConfigsMap[f] = struct{}{} + } + + result := newUpdateResult() + + // 2: Check the config list and mark any missing configs as "to be removed" + for _, configs := range r.configs { + for path := range configs { + if _, ok := clientConfigsMap[path]; !ok { + result.removed = append(result.removed, path) + parsedPath, err := parseConfigPath(path) + if err != nil { + return nil, err + } + result.productsUpdated[parsedPath.Product] = true + } + } + } + + // 3: For all the files referenced in this update + for _, path := range update.ClientConfigs { + targetFileMetadata, ok := updatedTargets.Targets[path] + if !ok { + return nil, fmt.Errorf("missing config file in TUF targets - %s", path) + } + + // 3.a: Extract the product and ID from the path + parsedPath, err := parseConfigPath(path) + if err != nil { + return nil, err + } + + // 3.b and 3.c: Check if this configuration is either new or has been modified + storedMetadata, exists := r.metadata[path] + if exists && hashesEqual(targetFileMetadata.Hashes, storedMetadata.Hashes) { + continue + } + + // 3.d: Ensure that the raw configuration file is present in the + // update payload. + raw, ok := update.TargetFiles[path] + if !ok { + return nil, fmt.Errorf("missing update file - %s", path) + } + + // TUF: Validate the hash of the raw target file and ensure that it matches + // the TUF metadata + err = validateTargetFileHash(targetFileMetadata, raw) + if err != nil { + return nil, fmt.Errorf("error validating %s hash with TUF metadata - %v", path, err) + } + + // 3.e: Deserialize the configuration. + // 3.f: Store the update details for application later + // + // Note: We don't have to worry about extra fields as mentioned + // in the RFC because the encoding/json library handles that for us. + m, err := newConfigMetadata(parsedPath, targetFileMetadata) + if err != nil { + return nil, err + } + config, err := parseConfig(parsedPath.Product, raw, m) + if err != nil { + return nil, err + } + result.metadata[path] = m + result.changed[parsedPath.Product][path] = config + result.productsUpdated[parsedPath.Product] = true + } + + // 4.a: Store the new targets.signed.custom.opaque_client_state + // TUF: Store the updated roots now that everything has validated + if r.tufVerificationEnabled { + r.tufRootsClient = tmpRootClient + } else if update.TUFRoots != nil && len(update.TUFRoots) > 0 { + v, err := extractRootVersion(update.TUFRoots[len(update.TUFRoots)-1]) + if err != nil { + return nil, err + } + r.latestRootVersion = v + } + r.latestTargets = updatedTargets + if r.latestTargets.Custom != nil { + r.opaqueBackendState = extractOpaqueBackendState(*r.latestTargets.Custom) + } + + // Upstream may not want to take any actions if the update result doesn't + // change any configs. + if result.isEmpty() { + return nil, nil + } + + changedProducts := make([]string, 0) + for product, updated := range result.productsUpdated { + if updated { + changedProducts = append(changedProducts, product) + } + } + + // 4.b/4.rave the new state and apply cleanups + r.applyUpdateResult(update, result) + + return changedProducts, nil +} + +// UpdateApplyStatus updates the config's metadata to reflect its processing state +// Can be used after a call to Update() in order to tell the repository which config was acked, which +// wasn't and which errors occurred while processing. +// Note: it is the responsibility of the caller to ensure that no new Update() call was made between +// the first Update() call and the call to UpdateApplyStatus() so as to keep the repository state accurate. +func (r *Repository) UpdateApplyStatus(cfgPath string, status ApplyStatus) { + if m, ok := r.metadata[cfgPath]; ok { + m.ApplyStatus = status + r.metadata[cfgPath] = m + } +} + +func (r *Repository) getConfigs(product string) map[string]interface{} { + configs, ok := r.configs[product] + if !ok { + return nil + } + + return configs +} + +// applyUpdateResult changes the state of the client based on the given update. +// +// The update is guaranteed to succeed at this point, having been vetted and the details +// needed to apply the update stored in the `updateResult`. +func (r *Repository) applyUpdateResult(update Update, result updateResult) { + // 4.b Save all the updated and new config files + for product, configs := range result.changed { + for path, config := range configs { + m := r.configs[product] + m[path] = config + } + } + for path, metadata := range result.metadata { + r.metadata[path] = metadata + } + + // 5.b Clean up the cache of any removed configs + for _, path := range result.removed { + delete(r.metadata, path) + for _, configs := range r.configs { + delete(configs, path) + } + } +} + +// CurrentState returns all of the information needed to +// make an update for new configurations. +func (r *Repository) CurrentState() (RepositoryState, error) { + var configs []ConfigState + var cached []CachedFile + + for path, metadata := range r.metadata { + configs = append(configs, configStateFromMetadata(metadata)) + cached = append(cached, cachedFileFromMetadata(path, metadata)) + } + + var latestRootVersion int64 + if r.tufVerificationEnabled { + root, err := r.tufRootsClient.latestRoot() + if err != nil { + return RepositoryState{}, err + } + latestRootVersion = root.Version + } else { + latestRootVersion = r.latestRootVersion + } + + return RepositoryState{ + Configs: configs, + CachedFiles: cached, + TargetsVersion: r.latestTargets.Version, + RootsVersion: latestRootVersion, + OpaqueBackendState: r.opaqueBackendState, + }, nil +} + +// An updateResult allows the client to apply the update as a transaction +// after validating all required preconditions +type updateResult struct { + removed []string + metadata map[string]Metadata + changed map[string]map[string]interface{} + productsUpdated map[string]bool +} + +func newUpdateResult() updateResult { + changed := make(map[string]map[string]interface{}) + + for product := range validProducts { + changed[product] = make(map[string]interface{}) + } + + return updateResult{ + removed: make([]string, 0), + metadata: make(map[string]Metadata), + changed: changed, + productsUpdated: map[string]bool{}, + } +} + +func (ur updateResult) Log() { + log.Printf("Removed Configs: %v", ur.removed) + + var b strings.Builder + b.WriteString("Changed configs: [") + for path := range ur.metadata { + b.WriteString(path) + b.WriteString(" ") + } + b.WriteString("]") + + log.Println(b.String()) +} + +func (ur updateResult) isEmpty() bool { + return len(ur.removed) == 0 && len(ur.metadata) == 0 +} + +func configStateFromMetadata(m Metadata) ConfigState { + return ConfigState{ + Product: m.Product, + ID: m.ID, + Version: m.Version, + ApplyStatus: m.ApplyStatus, + } +} + +func cachedFileFromMetadata(path string, m Metadata) CachedFile { + return CachedFile{ + Path: path, + Length: m.RawLength, + Hashes: m.Hashes, + } +} + +// hashesEqual checks if the hash values in the TUF metadata file match the stored +// hash values for a given config +func hashesEqual(tufHashes data.Hashes, storedHashes map[string][]byte) bool { + for algorithm, value := range tufHashes { + v, ok := storedHashes[algorithm] + if !ok { + continue + } + + if !bytes.Equal(value, v) { + return false + } + } + + return true +} + +func extractOpaqueBackendState(targetsCustom []byte) []byte { + state := struct { + State []byte `json:"opaque_backend_state"` + }{nil} + + err := json.Unmarshal(targetsCustom, &state) + if err != nil { + return []byte{} + } + + return state.State +} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/tuf.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/tuf.go new file mode 100644 index 000000000..f67ab9c19 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/tuf.go @@ -0,0 +1,233 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2022-present Datadog, Inc. + +package state + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "strconv" + "strings" + + "github.com/DataDog/go-tuf/client" + "github.com/DataDog/go-tuf/data" + "github.com/DataDog/go-tuf/util" + "github.com/DataDog/go-tuf/verify" +) + +type tufRootsClient struct { + rootClient *client.Client + rootLocalStore client.LocalStore + rootRemoteStore *rootClientRemoteStore +} + +func newTufRootsClient(root []byte) (*tufRootsClient, error) { + rootLocalStore := client.MemoryLocalStore() + rootRemoteStore := &rootClientRemoteStore{} + rootClient := client.NewClient(rootLocalStore, rootRemoteStore) + + err := rootClient.Init(root) + if err != nil { + return nil, err + } + + return &tufRootsClient{ + rootClient: rootClient, + rootLocalStore: rootLocalStore, + rootRemoteStore: rootRemoteStore, + }, nil +} + +func (trc *tufRootsClient) clone() (*tufRootsClient, error) { + root, err := trc.latestRootRaw() + if err != nil { + return nil, err + } + + return newTufRootsClient(root) +} + +func (trc *tufRootsClient) updateRoots(newRoots [][]byte) error { + if len(newRoots) == 0 { + return nil + } + + trc.rootRemoteStore.roots = append(trc.rootRemoteStore.roots, newRoots...) + + return trc.rootClient.UpdateRoots() +} + +func (trc *tufRootsClient) latestRoot() (*data.Root, error) { + raw, err := trc.latestRootRaw() + if err != nil { + return nil, err + } + + return unsafeUnmarshalRoot(raw) +} + +func (trc *tufRootsClient) latestRootRaw() ([]byte, error) { + metas, err := trc.rootLocalStore.GetMeta() + if err != nil { + return nil, err + } + rawRoot := metas["root.json"] + + return rawRoot, nil +} + +func (trc *tufRootsClient) validateTargets(rawTargets []byte) (*data.Targets, error) { + root, err := trc.latestRoot() + if err != nil { + return nil, err + } + + db := verify.NewDB() + for _, key := range root.Keys { + for _, id := range key.IDs() { + if err := db.AddKey(id, key); err != nil { + return nil, err + } + } + } + targetsRole, hasRoleTargets := root.Roles["targets"] + if !hasRoleTargets { + return nil, fmt.Errorf("root is missing a targets role") + } + role := &data.Role{Threshold: targetsRole.Threshold, KeyIDs: targetsRole.KeyIDs} + if err := db.AddRole("targets", role); err != nil { + return nil, fmt.Errorf("could not add targets role to db: %v", err) + } + var targets data.Targets + err = db.Unmarshal(rawTargets, &targets, "targets", 0) + if err != nil { + return nil, err + } + + return &targets, nil +} + +type rootClientRemoteStore struct { + roots [][]byte +} + +func (s *rootClientRemoteStore) GetMeta(name string) (stream io.ReadCloser, size int64, err error) { + metaPath, err := parseMetaPath(name) + if err != nil { + return nil, 0, err + } + if metaPath.role != roleRoot || !metaPath.versionSet { + return nil, 0, client.ErrNotFound{File: name} + } + for _, root := range s.roots { + parsedRoot, err := unsafeUnmarshalRoot(root) + if err != nil { + return nil, 0, err + } + if parsedRoot.Version == metaPath.version { + return io.NopCloser(bytes.NewReader(root)), int64(len(root)), nil + } + } + return nil, 0, client.ErrNotFound{File: name} +} + +func (s *rootClientRemoteStore) GetTarget(path string) (stream io.ReadCloser, size int64, err error) { + return nil, 0, client.ErrNotFound{File: path} +} + +type role string + +const ( + roleRoot role = "root" +) + +type metaPath struct { + role role + version int64 + versionSet bool +} + +func parseMetaPath(rawMetaPath string) (metaPath, error) { + splitRawMetaPath := strings.SplitN(rawMetaPath, ".", 3) + if len(splitRawMetaPath) != 2 && len(splitRawMetaPath) != 3 { + return metaPath{}, fmt.Errorf("invalid metadata path '%s'", rawMetaPath) + } + suffix := splitRawMetaPath[len(splitRawMetaPath)-1] + if suffix != "json" { + return metaPath{}, fmt.Errorf("invalid metadata path (suffix) '%s'", rawMetaPath) + } + rawRole := splitRawMetaPath[len(splitRawMetaPath)-2] + if rawRole == "" { + return metaPath{}, fmt.Errorf("invalid metadata path (role) '%s'", rawMetaPath) + } + if len(splitRawMetaPath) == 2 { + return metaPath{ + role: role(rawRole), + }, nil + } + rawVersion, err := strconv.ParseInt(splitRawMetaPath[0], 10, 64) + if err != nil { + return metaPath{}, fmt.Errorf("invalid metadata path (version) '%s': %w", rawMetaPath, err) + } + return metaPath{ + role: role(rawRole), + version: rawVersion, + versionSet: true, + }, nil +} + +func validateTargetFileHash(targetMeta data.TargetFileMeta, targetFile []byte) error { + if len(targetMeta.HashAlgorithms()) == 0 { + return fmt.Errorf("target file has no hash") + } + generatedMeta, err := util.GenerateFileMeta(bytes.NewBuffer(targetFile), targetMeta.HashAlgorithms()...) + if err != nil { + return err + } + err = util.FileMetaEqual(targetMeta.FileMeta, generatedMeta) + if err != nil { + return err + } + return nil +} + +func unsafeUnmarshalRoot(raw []byte) (*data.Root, error) { + var signedRoot data.Signed + err := json.Unmarshal(raw, &signedRoot) + if err != nil { + return nil, err + } + var root data.Root + err = json.Unmarshal(signedRoot.Signed, &root) + if err != nil { + return nil, err + } + return &root, err +} + +func unsafeUnmarshalTargets(raw []byte) (*data.Targets, error) { + var signedTargets data.Signed + err := json.Unmarshal(raw, &signedTargets) + if err != nil { + return nil, err + } + var targets data.Targets + err = json.Unmarshal(signedTargets.Signed, &targets) + if err != nil { + return nil, err + } + return &targets, err +} + +func extractRootVersion(raw []byte) (int64, error) { + root, err := unsafeUnmarshalRoot(raw) + if err != nil { + return 0, err + } + + return root.Version, nil +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/LICENSE.txt b/vendor/github.com/DataDog/datadog-go/v5/LICENSE.txt new file mode 100644 index 000000000..97cd06d7f --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2015 Datadog, Inc + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/README.md b/vendor/github.com/DataDog/datadog-go/v5/statsd/README.md new file mode 100644 index 000000000..2fc899687 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/README.md @@ -0,0 +1,4 @@ +## Overview + +Package `statsd` provides a Go [dogstatsd](http://docs.datadoghq.com/guides/dogstatsd/) client. Dogstatsd extends Statsd, adding tags +and histograms. diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/aggregator.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/aggregator.go new file mode 100644 index 000000000..ae4723c42 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/aggregator.go @@ -0,0 +1,290 @@ +package statsd + +import ( + "strings" + "sync" + "sync/atomic" + "time" +) + +type ( + countsMap map[string]*countMetric + gaugesMap map[string]*gaugeMetric + setsMap map[string]*setMetric + bufferedMetricMap map[string]*bufferedMetric +) + +type aggregator struct { + nbContextGauge uint64 + nbContextCount uint64 + nbContextSet uint64 + + countsM sync.RWMutex + gaugesM sync.RWMutex + setsM sync.RWMutex + + gauges gaugesMap + counts countsMap + sets setsMap + histograms bufferedMetricContexts + distributions bufferedMetricContexts + timings bufferedMetricContexts + + closed chan struct{} + + client *Client + + // aggregator implements channelMode mechanism to receive histograms, + // distributions and timings. Since they need sampling they need to + // lock for random. When using both channelMode and ExtendedAggregation + // we don't want goroutine to fight over the lock. + inputMetrics chan metric + stopChannelMode chan struct{} + wg sync.WaitGroup +} + +func newAggregator(c *Client) *aggregator { + return &aggregator{ + client: c, + counts: countsMap{}, + gauges: gaugesMap{}, + sets: setsMap{}, + histograms: newBufferedContexts(newHistogramMetric), + distributions: newBufferedContexts(newDistributionMetric), + timings: newBufferedContexts(newTimingMetric), + closed: make(chan struct{}), + stopChannelMode: make(chan struct{}), + } +} + +func (a *aggregator) start(flushInterval time.Duration) { + ticker := time.NewTicker(flushInterval) + + go func() { + for { + select { + case <-ticker.C: + a.flush() + case <-a.closed: + ticker.Stop() + return + } + } + }() +} + +func (a *aggregator) startReceivingMetric(bufferSize int, nbWorkers int) { + a.inputMetrics = make(chan metric, bufferSize) + for i := 0; i < nbWorkers; i++ { + a.wg.Add(1) + go a.pullMetric() + } +} + +func (a *aggregator) stopReceivingMetric() { + close(a.stopChannelMode) + a.wg.Wait() +} + +func (a *aggregator) stop() { + a.closed <- struct{}{} +} + +func (a *aggregator) pullMetric() { + for { + select { + case m := <-a.inputMetrics: + switch m.metricType { + case histogram: + a.histogram(m.name, m.fvalue, m.tags, m.rate) + case distribution: + a.distribution(m.name, m.fvalue, m.tags, m.rate) + case timing: + a.timing(m.name, m.fvalue, m.tags, m.rate) + } + case <-a.stopChannelMode: + a.wg.Done() + return + } + } +} + +func (a *aggregator) flush() { + for _, m := range a.flushMetrics() { + a.client.sendBlocking(m) + } +} + +func (a *aggregator) flushTelemetryMetrics(t *Telemetry) { + if a == nil { + // aggregation is disabled + return + } + + t.AggregationNbContextGauge = atomic.LoadUint64(&a.nbContextGauge) + t.AggregationNbContextCount = atomic.LoadUint64(&a.nbContextCount) + t.AggregationNbContextSet = atomic.LoadUint64(&a.nbContextSet) + t.AggregationNbContextHistogram = a.histograms.getNbContext() + t.AggregationNbContextDistribution = a.distributions.getNbContext() + t.AggregationNbContextTiming = a.timings.getNbContext() +} + +func (a *aggregator) flushMetrics() []metric { + metrics := []metric{} + + // We reset the values to avoid sending 'zero' values for metrics not + // sampled during this flush interval + + a.setsM.Lock() + sets := a.sets + a.sets = setsMap{} + a.setsM.Unlock() + + for _, s := range sets { + metrics = append(metrics, s.flushUnsafe()...) + } + + a.gaugesM.Lock() + gauges := a.gauges + a.gauges = gaugesMap{} + a.gaugesM.Unlock() + + for _, g := range gauges { + metrics = append(metrics, g.flushUnsafe()) + } + + a.countsM.Lock() + counts := a.counts + a.counts = countsMap{} + a.countsM.Unlock() + + for _, c := range counts { + metrics = append(metrics, c.flushUnsafe()) + } + + metrics = a.histograms.flush(metrics) + metrics = a.distributions.flush(metrics) + metrics = a.timings.flush(metrics) + + atomic.AddUint64(&a.nbContextCount, uint64(len(counts))) + atomic.AddUint64(&a.nbContextGauge, uint64(len(gauges))) + atomic.AddUint64(&a.nbContextSet, uint64(len(sets))) + return metrics +} + +func getContext(name string, tags []string) string { + c, _ := getContextAndTags(name, tags) + return c +} + +func getContextAndTags(name string, tags []string) (string, string) { + if len(tags) == 0 { + return name + nameSeparatorSymbol, "" + } + n := len(name) + len(nameSeparatorSymbol) + len(tagSeparatorSymbol)*(len(tags)-1) + for _, s := range tags { + n += len(s) + } + + var sb strings.Builder + sb.Grow(n) + sb.WriteString(name) + sb.WriteString(nameSeparatorSymbol) + sb.WriteString(tags[0]) + for _, s := range tags[1:] { + sb.WriteString(tagSeparatorSymbol) + sb.WriteString(s) + } + + s := sb.String() + + return s, s[len(name)+len(nameSeparatorSymbol):] +} + +func (a *aggregator) count(name string, value int64, tags []string) error { + context := getContext(name, tags) + a.countsM.RLock() + if count, found := a.counts[context]; found { + count.sample(value) + a.countsM.RUnlock() + return nil + } + a.countsM.RUnlock() + + a.countsM.Lock() + // Check if another goroutines hasn't created the value betwen the RUnlock and 'Lock' + if count, found := a.counts[context]; found { + count.sample(value) + a.countsM.Unlock() + return nil + } + + a.counts[context] = newCountMetric(name, value, tags) + a.countsM.Unlock() + return nil +} + +func (a *aggregator) gauge(name string, value float64, tags []string) error { + context := getContext(name, tags) + a.gaugesM.RLock() + if gauge, found := a.gauges[context]; found { + gauge.sample(value) + a.gaugesM.RUnlock() + return nil + } + a.gaugesM.RUnlock() + + gauge := newGaugeMetric(name, value, tags) + + a.gaugesM.Lock() + // Check if another goroutines hasn't created the value betwen the 'RUnlock' and 'Lock' + if gauge, found := a.gauges[context]; found { + gauge.sample(value) + a.gaugesM.Unlock() + return nil + } + a.gauges[context] = gauge + a.gaugesM.Unlock() + return nil +} + +func (a *aggregator) set(name string, value string, tags []string) error { + context := getContext(name, tags) + a.setsM.RLock() + if set, found := a.sets[context]; found { + set.sample(value) + a.setsM.RUnlock() + return nil + } + a.setsM.RUnlock() + + a.setsM.Lock() + // Check if another goroutines hasn't created the value betwen the 'RUnlock' and 'Lock' + if set, found := a.sets[context]; found { + set.sample(value) + a.setsM.Unlock() + return nil + } + a.sets[context] = newSetMetric(name, value, tags) + a.setsM.Unlock() + return nil +} + +// Only histograms, distributions and timings are sampled with a rate since we +// only pack them in on message instead of aggregating them. Discarding the +// sample rate will have impacts on the CPU and memory usage of the Agent. + +// type alias for Client.sendToAggregator +type bufferedMetricSampleFunc func(name string, value float64, tags []string, rate float64) error + +func (a *aggregator) histogram(name string, value float64, tags []string, rate float64) error { + return a.histograms.sample(name, value, tags, rate) +} + +func (a *aggregator) distribution(name string, value float64, tags []string, rate float64) error { + return a.distributions.sample(name, value, tags, rate) +} + +func (a *aggregator) timing(name string, value float64, tags []string, rate float64) error { + return a.timings.sample(name, value, tags, rate) +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/buffer.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/buffer.go new file mode 100644 index 000000000..f7bb8b0aa --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/buffer.go @@ -0,0 +1,197 @@ +package statsd + +import ( + "strconv" +) + +// MessageTooLongError is an error returned when a sample, event or service check is too large once serialized. See +// WithMaxBytesPerPayload option for more details. +type MessageTooLongError struct{} + +func (e MessageTooLongError) Error() string { + return "message too long. See 'WithMaxBytesPerPayload' documentation." +} + +var errBufferFull = MessageTooLongError{} + +type partialWriteError string + +func (e partialWriteError) Error() string { return string(e) } + +const errPartialWrite = partialWriteError("value partially written") + +const metricOverhead = 512 + +// statsdBuffer is a buffer containing statsd messages +// this struct methods are NOT safe for concurent use +type statsdBuffer struct { + buffer []byte + maxSize int + maxElements int + elementCount int +} + +func newStatsdBuffer(maxSize, maxElements int) *statsdBuffer { + return &statsdBuffer{ + buffer: make([]byte, 0, maxSize+metricOverhead), // pre-allocate the needed size + metricOverhead to avoid having Go re-allocate on it's own if an element does not fit + maxSize: maxSize, + maxElements: maxElements, + } +} + +func (b *statsdBuffer) writeGauge(namespace string, globalTags []string, name string, value float64, tags []string, rate float64, timestamp int64) error { + if b.elementCount >= b.maxElements { + return errBufferFull + } + originalBuffer := b.buffer + b.buffer = appendGauge(b.buffer, namespace, globalTags, name, value, tags, rate) + b.buffer = appendTimestamp(b.buffer, timestamp) + b.writeSeparator() + return b.validateNewElement(originalBuffer) +} + +func (b *statsdBuffer) writeCount(namespace string, globalTags []string, name string, value int64, tags []string, rate float64, timestamp int64) error { + if b.elementCount >= b.maxElements { + return errBufferFull + } + originalBuffer := b.buffer + b.buffer = appendCount(b.buffer, namespace, globalTags, name, value, tags, rate) + b.buffer = appendTimestamp(b.buffer, timestamp) + b.writeSeparator() + return b.validateNewElement(originalBuffer) +} + +func (b *statsdBuffer) writeHistogram(namespace string, globalTags []string, name string, value float64, tags []string, rate float64) error { + if b.elementCount >= b.maxElements { + return errBufferFull + } + originalBuffer := b.buffer + b.buffer = appendHistogram(b.buffer, namespace, globalTags, name, value, tags, rate) + b.writeSeparator() + return b.validateNewElement(originalBuffer) +} + +// writeAggregated serialized as many values as possible in the current buffer and return the position in values where it stopped. +func (b *statsdBuffer) writeAggregated(metricSymbol []byte, namespace string, globalTags []string, name string, values []float64, tags string, tagSize int, precision int) (int, error) { + if b.elementCount >= b.maxElements { + return 0, errBufferFull + } + + originalBuffer := b.buffer + b.buffer = appendHeader(b.buffer, namespace, name) + + // buffer already full + if len(b.buffer)+tagSize > b.maxSize { + b.buffer = originalBuffer + return 0, errBufferFull + } + + // We add as many value as possible + var position int + for idx, v := range values { + previousBuffer := b.buffer + if idx != 0 { + b.buffer = append(b.buffer, ':') + } + + b.buffer = strconv.AppendFloat(b.buffer, v, 'f', precision, 64) + + // Should we stop serializing and switch to another buffer + if len(b.buffer)+tagSize > b.maxSize { + b.buffer = previousBuffer + break + } + position = idx + 1 + } + + // we could not add a single value + if position == 0 { + b.buffer = originalBuffer + return 0, errBufferFull + } + + b.buffer = append(b.buffer, '|') + b.buffer = append(b.buffer, metricSymbol...) + b.buffer = appendTagsAggregated(b.buffer, globalTags, tags) + b.buffer = appendContainerID(b.buffer) + b.writeSeparator() + b.elementCount++ + + if position != len(values) { + return position, errPartialWrite + } + return position, nil + +} + +func (b *statsdBuffer) writeDistribution(namespace string, globalTags []string, name string, value float64, tags []string, rate float64) error { + if b.elementCount >= b.maxElements { + return errBufferFull + } + originalBuffer := b.buffer + b.buffer = appendDistribution(b.buffer, namespace, globalTags, name, value, tags, rate) + b.writeSeparator() + return b.validateNewElement(originalBuffer) +} + +func (b *statsdBuffer) writeSet(namespace string, globalTags []string, name string, value string, tags []string, rate float64) error { + if b.elementCount >= b.maxElements { + return errBufferFull + } + originalBuffer := b.buffer + b.buffer = appendSet(b.buffer, namespace, globalTags, name, value, tags, rate) + b.writeSeparator() + return b.validateNewElement(originalBuffer) +} + +func (b *statsdBuffer) writeTiming(namespace string, globalTags []string, name string, value float64, tags []string, rate float64) error { + if b.elementCount >= b.maxElements { + return errBufferFull + } + originalBuffer := b.buffer + b.buffer = appendTiming(b.buffer, namespace, globalTags, name, value, tags, rate) + b.writeSeparator() + return b.validateNewElement(originalBuffer) +} + +func (b *statsdBuffer) writeEvent(event *Event, globalTags []string) error { + if b.elementCount >= b.maxElements { + return errBufferFull + } + originalBuffer := b.buffer + b.buffer = appendEvent(b.buffer, event, globalTags) + b.writeSeparator() + return b.validateNewElement(originalBuffer) +} + +func (b *statsdBuffer) writeServiceCheck(serviceCheck *ServiceCheck, globalTags []string) error { + if b.elementCount >= b.maxElements { + return errBufferFull + } + originalBuffer := b.buffer + b.buffer = appendServiceCheck(b.buffer, serviceCheck, globalTags) + b.writeSeparator() + return b.validateNewElement(originalBuffer) +} + +func (b *statsdBuffer) validateNewElement(originalBuffer []byte) error { + if len(b.buffer) > b.maxSize { + b.buffer = originalBuffer + return errBufferFull + } + b.elementCount++ + return nil +} + +func (b *statsdBuffer) writeSeparator() { + b.buffer = append(b.buffer, '\n') +} + +func (b *statsdBuffer) reset() { + b.buffer = b.buffer[:0] + b.elementCount = 0 +} + +func (b *statsdBuffer) bytes() []byte { + return b.buffer +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/buffer_pool.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/buffer_pool.go new file mode 100644 index 000000000..7a3e3c9d2 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/buffer_pool.go @@ -0,0 +1,40 @@ +package statsd + +type bufferPool struct { + pool chan *statsdBuffer + bufferMaxSize int + bufferMaxElements int +} + +func newBufferPool(poolSize, bufferMaxSize, bufferMaxElements int) *bufferPool { + p := &bufferPool{ + pool: make(chan *statsdBuffer, poolSize), + bufferMaxSize: bufferMaxSize, + bufferMaxElements: bufferMaxElements, + } + for i := 0; i < poolSize; i++ { + p.addNewBuffer() + } + return p +} + +func (p *bufferPool) addNewBuffer() { + p.pool <- newStatsdBuffer(p.bufferMaxSize, p.bufferMaxElements) +} + +func (p *bufferPool) borrowBuffer() *statsdBuffer { + select { + case b := <-p.pool: + return b + default: + return newStatsdBuffer(p.bufferMaxSize, p.bufferMaxElements) + } +} + +func (p *bufferPool) returnBuffer(buffer *statsdBuffer) { + buffer.reset() + select { + case p.pool <- buffer: + default: + } +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/buffered_metric_context.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/buffered_metric_context.go new file mode 100644 index 000000000..41404d98e --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/buffered_metric_context.go @@ -0,0 +1,82 @@ +package statsd + +import ( + "math/rand" + "sync" + "sync/atomic" + "time" +) + +// bufferedMetricContexts represent the contexts for Histograms, Distributions +// and Timing. Since those 3 metric types behave the same way and are sampled +// with the same type they're represented by the same class. +type bufferedMetricContexts struct { + nbContext uint64 + mutex sync.RWMutex + values bufferedMetricMap + newMetric func(string, float64, string) *bufferedMetric + + // Each bufferedMetricContexts uses its own random source and random + // lock to prevent goroutines from contending for the lock on the + // "math/rand" package-global random source (e.g. calls like + // "rand.Float64()" must acquire a shared lock to get the next + // pseudorandom number). + random *rand.Rand + randomLock sync.Mutex +} + +func newBufferedContexts(newMetric func(string, float64, string) *bufferedMetric) bufferedMetricContexts { + return bufferedMetricContexts{ + values: bufferedMetricMap{}, + newMetric: newMetric, + // Note that calling "time.Now().UnixNano()" repeatedly quickly may return + // very similar values. That's fine for seeding the worker-specific random + // source because we just need an evenly distributed stream of float values. + // Do not use this random source for cryptographic randomness. + random: rand.New(rand.NewSource(time.Now().UnixNano())), + } +} + +func (bc *bufferedMetricContexts) flush(metrics []metric) []metric { + bc.mutex.Lock() + values := bc.values + bc.values = bufferedMetricMap{} + bc.mutex.Unlock() + + for _, d := range values { + metrics = append(metrics, d.flushUnsafe()) + } + atomic.AddUint64(&bc.nbContext, uint64(len(values))) + return metrics +} + +func (bc *bufferedMetricContexts) sample(name string, value float64, tags []string, rate float64) error { + if !shouldSample(rate, bc.random, &bc.randomLock) { + return nil + } + + context, stringTags := getContextAndTags(name, tags) + + bc.mutex.RLock() + if v, found := bc.values[context]; found { + v.sample(value) + bc.mutex.RUnlock() + return nil + } + bc.mutex.RUnlock() + + bc.mutex.Lock() + // Check if another goroutines hasn't created the value betwen the 'RUnlock' and 'Lock' + if v, found := bc.values[context]; found { + v.sample(value) + bc.mutex.Unlock() + return nil + } + bc.values[context] = bc.newMetric(name, value, stringTags) + bc.mutex.Unlock() + return nil +} + +func (bc *bufferedMetricContexts) getNbContext() uint64 { + return atomic.LoadUint64(&bc.nbContext) +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/container.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/container.go new file mode 100644 index 000000000..b2331e829 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/container.go @@ -0,0 +1,82 @@ +package statsd + +import ( + "bufio" + "fmt" + "io" + "os" + "regexp" + "sync" +) + +const ( + // cgroupPath is the path to the cgroup file where we can find the container id if one exists. + cgroupPath = "/proc/self/cgroup" +) + +const ( + uuidSource = "[0-9a-f]{8}[-_][0-9a-f]{4}[-_][0-9a-f]{4}[-_][0-9a-f]{4}[-_][0-9a-f]{12}" + containerSource = "[0-9a-f]{64}" + taskSource = "[0-9a-f]{32}-\\d+" +) + +var ( + // expLine matches a line in the /proc/self/cgroup file. It has a submatch for the last element (path), which contains the container ID. + expLine = regexp.MustCompile(`^\d+:[^:]*:(.+)$`) + + // expContainerID matches contained IDs and sources. Source: https://github.com/Qard/container-info/blob/master/index.js + expContainerID = regexp.MustCompile(fmt.Sprintf(`(%s|%s|%s)(?:.scope)?$`, uuidSource, containerSource, taskSource)) + + // containerID holds the container ID. + containerID = "" +) + +// parseContainerID finds the first container ID reading from r and returns it. +func parseContainerID(r io.Reader) string { + scn := bufio.NewScanner(r) + for scn.Scan() { + path := expLine.FindStringSubmatch(scn.Text()) + if len(path) != 2 { + // invalid entry, continue + continue + } + if parts := expContainerID.FindStringSubmatch(path[1]); len(parts) == 2 { + return parts[1] + } + } + return "" +} + +// readContainerID attempts to return the container ID from the provided file path or empty on failure. +func readContainerID(fpath string) string { + f, err := os.Open(fpath) + if err != nil { + return "" + } + defer f.Close() + return parseContainerID(f) +} + +// getContainerID returns the container ID configured at the client creation +// It can either be auto-discovered with origin detection or provided by the user. +// User-defined container ID is prioritized. +func getContainerID() string { + return containerID +} + +var initOnce sync.Once + +// initContainerID initializes the container ID. +// It can either be provided by the user or read from cgroups. +func initContainerID(userProvidedID string, cgroupFallback bool) { + initOnce.Do(func() { + if userProvidedID != "" { + containerID = userProvidedID + return + } + + if cgroupFallback { + containerID = readContainerID(cgroupPath) + } + }) +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/event.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/event.go new file mode 100644 index 000000000..a2ca4faf7 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/event.go @@ -0,0 +1,75 @@ +package statsd + +import ( + "fmt" + "time" +) + +// Events support +// EventAlertType and EventAlertPriority became exported types after this issue was submitted: https://github.com/DataDog/datadog-go/issues/41 +// The reason why they got exported is so that client code can directly use the types. + +// EventAlertType is the alert type for events +type EventAlertType string + +const ( + // Info is the "info" AlertType for events + Info EventAlertType = "info" + // Error is the "error" AlertType for events + Error EventAlertType = "error" + // Warning is the "warning" AlertType for events + Warning EventAlertType = "warning" + // Success is the "success" AlertType for events + Success EventAlertType = "success" +) + +// EventPriority is the event priority for events +type EventPriority string + +const ( + // Normal is the "normal" Priority for events + Normal EventPriority = "normal" + // Low is the "low" Priority for events + Low EventPriority = "low" +) + +// An Event is an object that can be posted to your DataDog event stream. +type Event struct { + // Title of the event. Required. + Title string + // Text is the description of the event. + Text string + // Timestamp is a timestamp for the event. If not provided, the dogstatsd + // server will set this to the current time. + Timestamp time.Time + // Hostname for the event. + Hostname string + // AggregationKey groups this event with others of the same key. + AggregationKey string + // Priority of the event. Can be statsd.Low or statsd.Normal. + Priority EventPriority + // SourceTypeName is a source type for the event. + SourceTypeName string + // AlertType can be statsd.Info, statsd.Error, statsd.Warning, or statsd.Success. + // If absent, the default value applied by the dogstatsd server is Info. + AlertType EventAlertType + // Tags for the event. + Tags []string +} + +// NewEvent creates a new event with the given title and text. Error checking +// against these values is done at send-time, or upon running e.Check. +func NewEvent(title, text string) *Event { + return &Event{ + Title: title, + Text: text, + } +} + +// Check verifies that an event is valid. +func (e *Event) Check() error { + if len(e.Title) == 0 { + return fmt.Errorf("statsd.Event title is required") + } + return nil +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/fnv1a.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/fnv1a.go new file mode 100644 index 000000000..03dc8a07c --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/fnv1a.go @@ -0,0 +1,39 @@ +package statsd + +const ( + // FNV-1a + offset32 = uint32(2166136261) + prime32 = uint32(16777619) + + // init32 is what 32 bits hash values should be initialized with. + init32 = offset32 +) + +// HashString32 returns the hash of s. +func hashString32(s string) uint32 { + return addString32(init32, s) +} + +// AddString32 adds the hash of s to the precomputed hash value h. +func addString32(h uint32, s string) uint32 { + i := 0 + n := (len(s) / 8) * 8 + + for i != n { + h = (h ^ uint32(s[i])) * prime32 + h = (h ^ uint32(s[i+1])) * prime32 + h = (h ^ uint32(s[i+2])) * prime32 + h = (h ^ uint32(s[i+3])) * prime32 + h = (h ^ uint32(s[i+4])) * prime32 + h = (h ^ uint32(s[i+5])) * prime32 + h = (h ^ uint32(s[i+6])) * prime32 + h = (h ^ uint32(s[i+7])) * prime32 + i += 8 + } + + for _, c := range s[i:] { + h = (h ^ uint32(c)) * prime32 + } + + return h +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/format.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/format.go new file mode 100644 index 000000000..f3ab9231f --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/format.go @@ -0,0 +1,280 @@ +package statsd + +import ( + "strconv" + "strings" +) + +var ( + gaugeSymbol = []byte("g") + countSymbol = []byte("c") + histogramSymbol = []byte("h") + distributionSymbol = []byte("d") + setSymbol = []byte("s") + timingSymbol = []byte("ms") + tagSeparatorSymbol = "," + nameSeparatorSymbol = ":" +) + +func appendHeader(buffer []byte, namespace string, name string) []byte { + if namespace != "" { + buffer = append(buffer, namespace...) + } + buffer = append(buffer, name...) + buffer = append(buffer, ':') + return buffer +} + +func appendRate(buffer []byte, rate float64) []byte { + if rate < 1 { + buffer = append(buffer, "|@"...) + buffer = strconv.AppendFloat(buffer, rate, 'f', -1, 64) + } + return buffer +} + +func appendWithoutNewlines(buffer []byte, s string) []byte { + // fastpath for strings without newlines + if strings.IndexByte(s, '\n') == -1 { + return append(buffer, s...) + } + + for _, b := range []byte(s) { + if b != '\n' { + buffer = append(buffer, b) + } + } + return buffer +} + +func appendTags(buffer []byte, globalTags []string, tags []string) []byte { + if len(globalTags) == 0 && len(tags) == 0 { + return buffer + } + buffer = append(buffer, "|#"...) + firstTag := true + + for _, tag := range globalTags { + if !firstTag { + buffer = append(buffer, tagSeparatorSymbol...) + } + buffer = appendWithoutNewlines(buffer, tag) + firstTag = false + } + for _, tag := range tags { + if !firstTag { + buffer = append(buffer, tagSeparatorSymbol...) + } + buffer = appendWithoutNewlines(buffer, tag) + firstTag = false + } + return buffer +} + +func appendTagsAggregated(buffer []byte, globalTags []string, tags string) []byte { + if len(globalTags) == 0 && tags == "" { + return buffer + } + + buffer = append(buffer, "|#"...) + firstTag := true + + for _, tag := range globalTags { + if !firstTag { + buffer = append(buffer, tagSeparatorSymbol...) + } + buffer = appendWithoutNewlines(buffer, tag) + firstTag = false + } + if tags != "" { + if !firstTag { + buffer = append(buffer, tagSeparatorSymbol...) + } + buffer = appendWithoutNewlines(buffer, tags) + } + return buffer +} + +func appendFloatMetric(buffer []byte, typeSymbol []byte, namespace string, globalTags []string, name string, value float64, tags []string, rate float64, precision int) []byte { + buffer = appendHeader(buffer, namespace, name) + buffer = strconv.AppendFloat(buffer, value, 'f', precision, 64) + buffer = append(buffer, '|') + buffer = append(buffer, typeSymbol...) + buffer = appendRate(buffer, rate) + buffer = appendTags(buffer, globalTags, tags) + buffer = appendContainerID(buffer) + return buffer +} + +func appendIntegerMetric(buffer []byte, typeSymbol []byte, namespace string, globalTags []string, name string, value int64, tags []string, rate float64) []byte { + buffer = appendHeader(buffer, namespace, name) + buffer = strconv.AppendInt(buffer, value, 10) + buffer = append(buffer, '|') + buffer = append(buffer, typeSymbol...) + buffer = appendRate(buffer, rate) + buffer = appendTags(buffer, globalTags, tags) + buffer = appendContainerID(buffer) + return buffer +} + +func appendStringMetric(buffer []byte, typeSymbol []byte, namespace string, globalTags []string, name string, value string, tags []string, rate float64) []byte { + buffer = appendHeader(buffer, namespace, name) + buffer = append(buffer, value...) + buffer = append(buffer, '|') + buffer = append(buffer, typeSymbol...) + buffer = appendRate(buffer, rate) + buffer = appendTags(buffer, globalTags, tags) + buffer = appendContainerID(buffer) + return buffer +} + +func appendGauge(buffer []byte, namespace string, globalTags []string, name string, value float64, tags []string, rate float64) []byte { + return appendFloatMetric(buffer, gaugeSymbol, namespace, globalTags, name, value, tags, rate, -1) +} + +func appendCount(buffer []byte, namespace string, globalTags []string, name string, value int64, tags []string, rate float64) []byte { + return appendIntegerMetric(buffer, countSymbol, namespace, globalTags, name, value, tags, rate) +} + +func appendHistogram(buffer []byte, namespace string, globalTags []string, name string, value float64, tags []string, rate float64) []byte { + return appendFloatMetric(buffer, histogramSymbol, namespace, globalTags, name, value, tags, rate, -1) +} + +func appendDistribution(buffer []byte, namespace string, globalTags []string, name string, value float64, tags []string, rate float64) []byte { + return appendFloatMetric(buffer, distributionSymbol, namespace, globalTags, name, value, tags, rate, -1) +} + +func appendSet(buffer []byte, namespace string, globalTags []string, name string, value string, tags []string, rate float64) []byte { + return appendStringMetric(buffer, setSymbol, namespace, globalTags, name, value, tags, rate) +} + +func appendTiming(buffer []byte, namespace string, globalTags []string, name string, value float64, tags []string, rate float64) []byte { + return appendFloatMetric(buffer, timingSymbol, namespace, globalTags, name, value, tags, rate, 6) +} + +func escapedEventTextLen(text string) int { + return len(text) + strings.Count(text, "\n") +} + +func appendEscapedEventText(buffer []byte, text string) []byte { + for _, b := range []byte(text) { + if b != '\n' { + buffer = append(buffer, b) + } else { + buffer = append(buffer, "\\n"...) + } + } + return buffer +} + +func appendEvent(buffer []byte, event *Event, globalTags []string) []byte { + escapedTextLen := escapedEventTextLen(event.Text) + + buffer = append(buffer, "_e{"...) + buffer = strconv.AppendInt(buffer, int64(len(event.Title)), 10) + buffer = append(buffer, tagSeparatorSymbol...) + buffer = strconv.AppendInt(buffer, int64(escapedTextLen), 10) + buffer = append(buffer, "}:"...) + buffer = append(buffer, event.Title...) + buffer = append(buffer, '|') + if escapedTextLen != len(event.Text) { + buffer = appendEscapedEventText(buffer, event.Text) + } else { + buffer = append(buffer, event.Text...) + } + + if !event.Timestamp.IsZero() { + buffer = append(buffer, "|d:"...) + buffer = strconv.AppendInt(buffer, int64(event.Timestamp.Unix()), 10) + } + + if len(event.Hostname) != 0 { + buffer = append(buffer, "|h:"...) + buffer = append(buffer, event.Hostname...) + } + + if len(event.AggregationKey) != 0 { + buffer = append(buffer, "|k:"...) + buffer = append(buffer, event.AggregationKey...) + } + + if len(event.Priority) != 0 { + buffer = append(buffer, "|p:"...) + buffer = append(buffer, event.Priority...) + } + + if len(event.SourceTypeName) != 0 { + buffer = append(buffer, "|s:"...) + buffer = append(buffer, event.SourceTypeName...) + } + + if len(event.AlertType) != 0 { + buffer = append(buffer, "|t:"...) + buffer = append(buffer, string(event.AlertType)...) + } + + buffer = appendTags(buffer, globalTags, event.Tags) + buffer = appendContainerID(buffer) + return buffer +} + +func appendEscapedServiceCheckText(buffer []byte, text string) []byte { + for i := 0; i < len(text); i++ { + if text[i] == '\n' { + buffer = append(buffer, "\\n"...) + } else if text[i] == 'm' && i+1 < len(text) && text[i+1] == ':' { + buffer = append(buffer, "m\\:"...) + i++ + } else { + buffer = append(buffer, text[i]) + } + } + return buffer +} + +func appendServiceCheck(buffer []byte, serviceCheck *ServiceCheck, globalTags []string) []byte { + buffer = append(buffer, "_sc|"...) + buffer = append(buffer, serviceCheck.Name...) + buffer = append(buffer, '|') + buffer = strconv.AppendInt(buffer, int64(serviceCheck.Status), 10) + + if !serviceCheck.Timestamp.IsZero() { + buffer = append(buffer, "|d:"...) + buffer = strconv.AppendInt(buffer, int64(serviceCheck.Timestamp.Unix()), 10) + } + + if len(serviceCheck.Hostname) != 0 { + buffer = append(buffer, "|h:"...) + buffer = append(buffer, serviceCheck.Hostname...) + } + + buffer = appendTags(buffer, globalTags, serviceCheck.Tags) + + if len(serviceCheck.Message) != 0 { + buffer = append(buffer, "|m:"...) + buffer = appendEscapedServiceCheckText(buffer, serviceCheck.Message) + } + + buffer = appendContainerID(buffer) + return buffer +} + +func appendSeparator(buffer []byte) []byte { + return append(buffer, '\n') +} + +func appendContainerID(buffer []byte) []byte { + if containerID := getContainerID(); len(containerID) > 0 { + buffer = append(buffer, "|c:"...) + buffer = append(buffer, containerID...) + } + return buffer +} + +func appendTimestamp(buffer []byte, timestamp int64) []byte { + if timestamp > noTimestamp { + buffer = append(buffer, "|T"...) + buffer = strconv.AppendInt(buffer, timestamp, 10) + } + return buffer +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/metrics.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/metrics.go new file mode 100644 index 000000000..82f11ac18 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/metrics.go @@ -0,0 +1,181 @@ +package statsd + +import ( + "math" + "sync" + "sync/atomic" +) + +/* +Those are metrics type that can be aggregated on the client side: + - Gauge + - Count + - Set +*/ + +type countMetric struct { + value int64 + name string + tags []string +} + +func newCountMetric(name string, value int64, tags []string) *countMetric { + return &countMetric{ + value: value, + name: name, + tags: copySlice(tags), + } +} + +func (c *countMetric) sample(v int64) { + atomic.AddInt64(&c.value, v) +} + +func (c *countMetric) flushUnsafe() metric { + return metric{ + metricType: count, + name: c.name, + tags: c.tags, + rate: 1, + ivalue: c.value, + } +} + +// Gauge + +type gaugeMetric struct { + value uint64 + name string + tags []string +} + +func newGaugeMetric(name string, value float64, tags []string) *gaugeMetric { + return &gaugeMetric{ + value: math.Float64bits(value), + name: name, + tags: copySlice(tags), + } +} + +func (g *gaugeMetric) sample(v float64) { + atomic.StoreUint64(&g.value, math.Float64bits(v)) +} + +func (g *gaugeMetric) flushUnsafe() metric { + return metric{ + metricType: gauge, + name: g.name, + tags: g.tags, + rate: 1, + fvalue: math.Float64frombits(g.value), + } +} + +// Set + +type setMetric struct { + data map[string]struct{} + name string + tags []string + sync.Mutex +} + +func newSetMetric(name string, value string, tags []string) *setMetric { + set := &setMetric{ + data: map[string]struct{}{}, + name: name, + tags: copySlice(tags), + } + set.data[value] = struct{}{} + return set +} + +func (s *setMetric) sample(v string) { + s.Lock() + defer s.Unlock() + s.data[v] = struct{}{} +} + +// Sets are aggregated on the agent side too. We flush the keys so a set from +// multiple application can be correctly aggregated on the agent side. +func (s *setMetric) flushUnsafe() []metric { + if len(s.data) == 0 { + return nil + } + + metrics := make([]metric, len(s.data)) + i := 0 + for value := range s.data { + metrics[i] = metric{ + metricType: set, + name: s.name, + tags: s.tags, + rate: 1, + svalue: value, + } + i++ + } + return metrics +} + +// Histograms, Distributions and Timings + +type bufferedMetric struct { + sync.Mutex + + data []float64 + name string + // Histograms and Distributions store tags as one string since we need + // to compute its size multiple time when serializing. + tags string + mtype metricType +} + +func (s *bufferedMetric) sample(v float64) { + s.Lock() + defer s.Unlock() + s.data = append(s.data, v) +} + +func (s *bufferedMetric) flushUnsafe() metric { + return metric{ + metricType: s.mtype, + name: s.name, + stags: s.tags, + rate: 1, + fvalues: s.data, + } +} + +type histogramMetric = bufferedMetric + +func newHistogramMetric(name string, value float64, stringTags string) *histogramMetric { + return &histogramMetric{ + data: []float64{value}, + name: name, + tags: stringTags, + mtype: histogramAggregated, + } +} + +type distributionMetric = bufferedMetric + +func newDistributionMetric(name string, value float64, stringTags string) *distributionMetric { + return &distributionMetric{ + data: []float64{value}, + name: name, + tags: stringTags, + mtype: distributionAggregated, + } +} + +type timingMetric = bufferedMetric + +func newTimingMetric(name string, value float64, stringTags string) *timingMetric { + return &timingMetric{ + data: []float64{value}, + name: name, + tags: stringTags, + mtype: timingAggregated, + } +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/noop.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/noop.go new file mode 100644 index 000000000..e92744f40 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/noop.go @@ -0,0 +1,106 @@ +package statsd + +import "time" + +// NoOpClient is a statsd client that does nothing. Can be useful in testing +// situations for library users. +type NoOpClient struct{} + +// Gauge does nothing and returns nil +func (n *NoOpClient) Gauge(name string, value float64, tags []string, rate float64) error { + return nil +} + +// GaugeWithTimestamp does nothing and returns nil +func (n *NoOpClient) GaugeWithTimestamp(name string, value float64, tags []string, rate float64, timestamp time.Time) error { + return nil +} + +// Count does nothing and returns nil +func (n *NoOpClient) Count(name string, value int64, tags []string, rate float64) error { + return nil +} + +// CountWithTimestamp does nothing and returns nil +func (n *NoOpClient) CountWithTimestamp(name string, value int64, tags []string, rate float64, timestamp time.Time) error { + return nil +} + +// Histogram does nothing and returns nil +func (n *NoOpClient) Histogram(name string, value float64, tags []string, rate float64) error { + return nil +} + +// Distribution does nothing and returns nil +func (n *NoOpClient) Distribution(name string, value float64, tags []string, rate float64) error { + return nil +} + +// Decr does nothing and returns nil +func (n *NoOpClient) Decr(name string, tags []string, rate float64) error { + return nil +} + +// Incr does nothing and returns nil +func (n *NoOpClient) Incr(name string, tags []string, rate float64) error { + return nil +} + +// Set does nothing and returns nil +func (n *NoOpClient) Set(name string, value string, tags []string, rate float64) error { + return nil +} + +// Timing does nothing and returns nil +func (n *NoOpClient) Timing(name string, value time.Duration, tags []string, rate float64) error { + return nil +} + +// TimeInMilliseconds does nothing and returns nil +func (n *NoOpClient) TimeInMilliseconds(name string, value float64, tags []string, rate float64) error { + return nil +} + +// Event does nothing and returns nil +func (n *NoOpClient) Event(e *Event) error { + return nil +} + +// SimpleEvent does nothing and returns nil +func (n *NoOpClient) SimpleEvent(title, text string) error { + return nil +} + +// ServiceCheck does nothing and returns nil +func (n *NoOpClient) ServiceCheck(sc *ServiceCheck) error { + return nil +} + +// SimpleServiceCheck does nothing and returns nil +func (n *NoOpClient) SimpleServiceCheck(name string, status ServiceCheckStatus) error { + return nil +} + +// Close does nothing and returns nil +func (n *NoOpClient) Close() error { + return nil +} + +// Flush does nothing and returns nil +func (n *NoOpClient) Flush() error { + return nil +} + +// IsClosed does nothing and return false +func (n *NoOpClient) IsClosed() bool { + return false +} + +// GetTelemetry does nothing and returns an empty Telemetry +func (n *NoOpClient) GetTelemetry() Telemetry { + return Telemetry{} +} + +// Verify that NoOpClient implements the ClientInterface. +// https://golang.org/doc/faq#guarantee_satisfies_interface +var _ ClientInterface = &NoOpClient{} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/options.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/options.go new file mode 100644 index 000000000..0728a976b --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/options.go @@ -0,0 +1,348 @@ +package statsd + +import ( + "fmt" + "math" + "strings" + "time" +) + +var ( + defaultNamespace = "" + defaultTags = []string{} + defaultMaxBytesPerPayload = 0 + defaultMaxMessagesPerPayload = math.MaxInt32 + defaultBufferPoolSize = 0 + defaultBufferFlushInterval = 100 * time.Millisecond + defaultWorkerCount = 32 + defaultSenderQueueSize = 0 + defaultWriteTimeout = 100 * time.Millisecond + defaultTelemetry = true + defaultReceivingMode = mutexMode + defaultChannelModeBufferSize = 4096 + defaultAggregationFlushInterval = 2 * time.Second + defaultAggregation = true + defaultExtendedAggregation = false + defaultOriginDetection = true +) + +// Options contains the configuration options for a client. +type Options struct { + namespace string + tags []string + maxBytesPerPayload int + maxMessagesPerPayload int + bufferPoolSize int + bufferFlushInterval time.Duration + workersCount int + senderQueueSize int + writeTimeout time.Duration + telemetry bool + receiveMode receivingMode + channelModeBufferSize int + aggregationFlushInterval time.Duration + aggregation bool + extendedAggregation bool + telemetryAddr string + originDetection bool + containerID string +} + +func resolveOptions(options []Option) (*Options, error) { + o := &Options{ + namespace: defaultNamespace, + tags: defaultTags, + maxBytesPerPayload: defaultMaxBytesPerPayload, + maxMessagesPerPayload: defaultMaxMessagesPerPayload, + bufferPoolSize: defaultBufferPoolSize, + bufferFlushInterval: defaultBufferFlushInterval, + workersCount: defaultWorkerCount, + senderQueueSize: defaultSenderQueueSize, + writeTimeout: defaultWriteTimeout, + telemetry: defaultTelemetry, + receiveMode: defaultReceivingMode, + channelModeBufferSize: defaultChannelModeBufferSize, + aggregationFlushInterval: defaultAggregationFlushInterval, + aggregation: defaultAggregation, + extendedAggregation: defaultExtendedAggregation, + originDetection: defaultOriginDetection, + } + + for _, option := range options { + err := option(o) + if err != nil { + return nil, err + } + } + + return o, nil +} + +// Option is a client option. Can return an error if validation fails. +type Option func(*Options) error + +// WithNamespace sets a string to be prepend to all metrics, events and service checks name. +// +// A '.' will automatically be added after the namespace if needed. For example a metrics 'test' with a namespace 'prod' +// will produce a final metric named 'prod.test'. +func WithNamespace(namespace string) Option { + return func(o *Options) error { + if strings.HasSuffix(namespace, ".") { + o.namespace = namespace + } else { + o.namespace = namespace + "." + } + return nil + } +} + +// WithTags sets global tags to be applied to every metrics, events and service checks. +func WithTags(tags []string) Option { + return func(o *Options) error { + o.tags = tags + return nil + } +} + +// WithMaxMessagesPerPayload sets the maximum number of metrics, events and/or service checks that a single payload can +// contain. +// +// The default is 'math.MaxInt32' which will most likely let the WithMaxBytesPerPayload option take precedence. This +// option can be set to `1` to create an unbuffered client (each metrics/event/service check will be send in its own +// payload to the agent). +func WithMaxMessagesPerPayload(maxMessagesPerPayload int) Option { + return func(o *Options) error { + o.maxMessagesPerPayload = maxMessagesPerPayload + return nil + } +} + +// WithMaxBytesPerPayload sets the maximum number of bytes a single payload can contain. Each sample, even and service +// check must be lower than this value once serialized or an `MessageTooLongError` is returned. +// +// The default value 0 which will set the option to the optimal size for the transport protocol used: 1432 for UDP and +// named pipe and 8192 for UDS. Those values offer the best performances. +// Be careful when changing this option, see +// https://docs.datadoghq.com/developers/dogstatsd/high_throughput/#ensure-proper-packet-sizes. +func WithMaxBytesPerPayload(MaxBytesPerPayload int) Option { + return func(o *Options) error { + o.maxBytesPerPayload = MaxBytesPerPayload + return nil + } +} + +// WithBufferPoolSize sets the size of the pool of buffers used to serialized metrics, events and service_checks. +// +// The default, 0, will set the option to the optimal size for the transport protocol used: 2048 for UDP and named pipe +// and 512 for UDS. +func WithBufferPoolSize(bufferPoolSize int) Option { + return func(o *Options) error { + o.bufferPoolSize = bufferPoolSize + return nil + } +} + +// WithBufferFlushInterval sets the interval after which the current buffer is flushed. +// +// A buffers are used to serialized data, they're flushed either when full (see WithMaxBytesPerPayload) or when it's +// been open for longer than this interval. +// +// With apps sending a high number of metrics/events/service_checks the interval rarely timeout. But with slow sending +// apps increasing this value will reduce the number of payload sent on the wire as more data is serialized in the same +// payload. +// +// Default is 100ms +func WithBufferFlushInterval(bufferFlushInterval time.Duration) Option { + return func(o *Options) error { + o.bufferFlushInterval = bufferFlushInterval + return nil + } +} + +// WithWorkersCount sets the number of workers that will be used to serialized data. +// +// Those workers allow the use of multiple buffers at the same time (see WithBufferPoolSize) to reduce lock contention. +// +// Default is 32. +func WithWorkersCount(workersCount int) Option { + return func(o *Options) error { + if workersCount < 1 { + return fmt.Errorf("workersCount must be a positive integer") + } + o.workersCount = workersCount + return nil + } +} + +// WithSenderQueueSize sets the size of the sender queue in number of buffers. +// +// After data has been serialized in a buffer they're pushed to a queue that the sender will consume and then each one +// ot the agent. +// +// The default value 0 will set the option to the optimal size for the transport protocol used: 2048 for UDP and named +// pipe and 512 for UDS. +func WithSenderQueueSize(senderQueueSize int) Option { + return func(o *Options) error { + o.senderQueueSize = senderQueueSize + return nil + } +} + +// WithWriteTimeout sets the timeout for network communication with the Agent, after this interval a payload is +// dropped. This is only used for UDS and named pipes connection. +func WithWriteTimeout(writeTimeout time.Duration) Option { + return func(o *Options) error { + o.writeTimeout = writeTimeout + return nil + } +} + +// WithChannelMode make the client use channels to receive metrics +// +// This determines how the client receive metrics from the app (for example when calling the `Gauge()` method). +// The client will either drop the metrics if its buffers are full (WithChannelMode option) or block the caller until the +// metric can be handled (WithMutexMode option). By default the client use mutexes. +// +// WithChannelMode uses a channel (see WithChannelModeBufferSize to configure its size) to receive metrics and drops metrics if +// the channel is full. Sending metrics in this mode is much slower that WithMutexMode (because of the channel), but will not +// block the application. This mode is made for application using many goroutines, sending the same metrics, at a very +// high volume. The goal is to not slow down the application at the cost of dropping metrics and having a lower max +// throughput. +func WithChannelMode() Option { + return func(o *Options) error { + o.receiveMode = channelMode + return nil + } +} + +// WithMutexMode will use mutex to receive metrics from the app throught the API. +// +// This determines how the client receive metrics from the app (for example when calling the `Gauge()` method). +// The client will either drop the metrics if its buffers are full (WithChannelMode option) or block the caller until the +// metric can be handled (WithMutexMode option). By default the client use mutexes. +// +// WithMutexMode uses mutexes to receive metrics which is much faster than channels but can cause some lock contention +// when used with a high number of goroutines sendint the same metrics. Mutexes are sharded based on the metrics name +// which limit mutex contention when multiple goroutines send different metrics (see WithWorkersCount). This is the +// default behavior which will produce the best throughput. +func WithMutexMode() Option { + return func(o *Options) error { + o.receiveMode = mutexMode + return nil + } +} + +// WithChannelModeBufferSize sets the size of the channel holding incoming metrics when WithChannelMode is used. +func WithChannelModeBufferSize(bufferSize int) Option { + return func(o *Options) error { + o.channelModeBufferSize = bufferSize + return nil + } +} + +// WithAggregationInterval sets the interval at which aggregated metrics are flushed. See WithClientSideAggregation and +// WithExtendedClientSideAggregation for more. +// +// The default interval is 2s. The interval must divide the Agent reporting period (default=10s) evenly to reduce "aliasing" +// that can cause values to appear irregular/spiky. +// +// For example a 3s aggregation interval will create spikes in the final graph: a application sending a count metric +// that increments at a constant 1000 time per second will appear noisy with an interval of 3s. This is because +// client-side aggregation would report every 3 seconds, while the agent is reporting every 10 seconds. This means in +// each agent bucket, the values are: 9000, 9000, 12000. +func WithAggregationInterval(interval time.Duration) Option { + return func(o *Options) error { + o.aggregationFlushInterval = interval + return nil + } +} + +// WithClientSideAggregation enables client side aggregation for Gauges, Counts and Sets. +func WithClientSideAggregation() Option { + return func(o *Options) error { + o.aggregation = true + return nil + } +} + +// WithoutClientSideAggregation disables client side aggregation. +func WithoutClientSideAggregation() Option { + return func(o *Options) error { + o.aggregation = false + o.extendedAggregation = false + return nil + } +} + +// WithExtendedClientSideAggregation enables client side aggregation for all types. This feature is only compatible with +// Agent's version >=6.25.0 && <7.0.0 or Agent's versions >=7.25.0. +func WithExtendedClientSideAggregation() Option { + return func(o *Options) error { + o.aggregation = true + o.extendedAggregation = true + return nil + } +} + +// WithoutTelemetry disables the client telemetry. +// +// More on this here: https://docs.datadoghq.com/developers/dogstatsd/high_throughput/#client-side-telemetry +func WithoutTelemetry() Option { + return func(o *Options) error { + o.telemetry = false + return nil + } +} + +// WithTelemetryAddr sets a different address for telemetry metrics. By default the same address as the client is used +// for telemetry. +// +// More on this here: https://docs.datadoghq.com/developers/dogstatsd/high_throughput/#client-side-telemetry +func WithTelemetryAddr(addr string) Option { + return func(o *Options) error { + o.telemetryAddr = addr + return nil + } +} + +// WithoutOriginDetection disables the client origin detection. +// When enabled, the client tries to discover its container ID and sends it to the Agent +// to enrich the metrics with container tags. +// Origin detection can also be disabled by configuring the environment variabe DD_ORIGIN_DETECTION_ENABLED=false +// The client tries to read the container ID by parsing the file /proc/self/cgroup, this is not supported on Windows. +// The client prioritizes the value passed via DD_ENTITY_ID (if set) over the container ID. +// +// More on this here: https://docs.datadoghq.com/developers/dogstatsd/?tab=kubernetes#origin-detection-over-udp +func WithoutOriginDetection() Option { + return func(o *Options) error { + o.originDetection = false + return nil + } +} + +// WithOriginDetection enables the client origin detection. +// This feature requires Datadog Agent version >=6.35.0 && <7.0.0 or Agent versions >=7.35.0. +// When enabled, the client tries to discover its container ID and sends it to the Agent +// to enrich the metrics with container tags. +// Origin detection can be disabled by configuring the environment variabe DD_ORIGIN_DETECTION_ENABLED=false +// The client tries to read the container ID by parsing the file /proc/self/cgroup, this is not supported on Windows. +// The client prioritizes the value passed via DD_ENTITY_ID (if set) over the container ID. +// +// More on this here: https://docs.datadoghq.com/developers/dogstatsd/?tab=kubernetes#origin-detection-over-udp +func WithOriginDetection() Option { + return func(o *Options) error { + o.originDetection = true + return nil + } +} + +// WithContainerID allows passing the container ID, this will be used by the Agent to enrich metrics with container tags. +// This feature requires Datadog Agent version >=6.35.0 && <7.0.0 or Agent versions >=7.35.0. +// When configured, the provided container ID is prioritized over the container ID discovered via Origin Detection. +// The client prioritizes the value passed via DD_ENTITY_ID (if set) over the container ID. +func WithContainerID(id string) Option { + return func(o *Options) error { + o.containerID = id + return nil + } +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/pipe.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/pipe.go new file mode 100644 index 000000000..84c38e966 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/pipe.go @@ -0,0 +1,13 @@ +// +build !windows + +package statsd + +import ( + "errors" + "io" + "time" +) + +func newWindowsPipeWriter(pipepath string, writeTimeout time.Duration) (io.WriteCloser, error) { + return nil, errors.New("Windows Named Pipes are only supported on Windows") +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/pipe_windows.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/pipe_windows.go new file mode 100644 index 000000000..5ab60f00c --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/pipe_windows.go @@ -0,0 +1,75 @@ +// +build windows + +package statsd + +import ( + "net" + "sync" + "time" + + "github.com/Microsoft/go-winio" +) + +type pipeWriter struct { + mu sync.RWMutex + conn net.Conn + timeout time.Duration + pipepath string +} + +func (p *pipeWriter) Write(data []byte) (n int, err error) { + conn, err := p.ensureConnection() + if err != nil { + return 0, err + } + + p.mu.RLock() + conn.SetWriteDeadline(time.Now().Add(p.timeout)) + p.mu.RUnlock() + + n, err = conn.Write(data) + if err != nil { + if e, ok := err.(net.Error); !ok || !e.Temporary() { + // disconnected; retry again on next attempt + p.mu.Lock() + p.conn = nil + p.mu.Unlock() + } + } + return n, err +} + +func (p *pipeWriter) ensureConnection() (net.Conn, error) { + p.mu.RLock() + conn := p.conn + p.mu.RUnlock() + if conn != nil { + return conn, nil + } + + // looks like we might need to connect - try again with write locking. + p.mu.Lock() + defer p.mu.Unlock() + if p.conn != nil { + return p.conn, nil + } + newconn, err := winio.DialPipe(p.pipepath, nil) + if err != nil { + return nil, err + } + p.conn = newconn + return newconn, nil +} + +func (p *pipeWriter) Close() error { + return p.conn.Close() +} + +func newWindowsPipeWriter(pipepath string, writeTimeout time.Duration) (*pipeWriter, error) { + // Defer connection establishment to first write + return &pipeWriter{ + conn: nil, + timeout: writeTimeout, + pipepath: pipepath, + }, nil +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/sender.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/sender.go new file mode 100644 index 000000000..500d53c40 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/sender.go @@ -0,0 +1,111 @@ +package statsd + +import ( + "io" + "sync/atomic" +) + +// senderTelemetry contains telemetry about the health of the sender +type senderTelemetry struct { + totalPayloadsSent uint64 + totalPayloadsDroppedQueueFull uint64 + totalPayloadsDroppedWriter uint64 + totalBytesSent uint64 + totalBytesDroppedQueueFull uint64 + totalBytesDroppedWriter uint64 +} + +type sender struct { + transport io.WriteCloser + pool *bufferPool + queue chan *statsdBuffer + telemetry *senderTelemetry + stop chan struct{} + flushSignal chan struct{} +} + +func newSender(transport io.WriteCloser, queueSize int, pool *bufferPool) *sender { + sender := &sender{ + transport: transport, + pool: pool, + queue: make(chan *statsdBuffer, queueSize), + telemetry: &senderTelemetry{}, + stop: make(chan struct{}), + flushSignal: make(chan struct{}), + } + + go sender.sendLoop() + return sender +} + +func (s *sender) send(buffer *statsdBuffer) { + select { + case s.queue <- buffer: + default: + atomic.AddUint64(&s.telemetry.totalPayloadsDroppedQueueFull, 1) + atomic.AddUint64(&s.telemetry.totalBytesDroppedQueueFull, uint64(len(buffer.bytes()))) + s.pool.returnBuffer(buffer) + } +} + +func (s *sender) write(buffer *statsdBuffer) { + _, err := s.transport.Write(buffer.bytes()) + if err != nil { + atomic.AddUint64(&s.telemetry.totalPayloadsDroppedWriter, 1) + atomic.AddUint64(&s.telemetry.totalBytesDroppedWriter, uint64(len(buffer.bytes()))) + } else { + atomic.AddUint64(&s.telemetry.totalPayloadsSent, 1) + atomic.AddUint64(&s.telemetry.totalBytesSent, uint64(len(buffer.bytes()))) + } + s.pool.returnBuffer(buffer) +} + +func (s *sender) flushTelemetryMetrics(t *Telemetry) { + t.TotalPayloadsSent = atomic.LoadUint64(&s.telemetry.totalPayloadsSent) + t.TotalPayloadsDroppedQueueFull = atomic.LoadUint64(&s.telemetry.totalPayloadsDroppedQueueFull) + t.TotalPayloadsDroppedWriter = atomic.LoadUint64(&s.telemetry.totalPayloadsDroppedWriter) + + t.TotalBytesSent = atomic.LoadUint64(&s.telemetry.totalBytesSent) + t.TotalBytesDroppedQueueFull = atomic.LoadUint64(&s.telemetry.totalBytesDroppedQueueFull) + t.TotalBytesDroppedWriter = atomic.LoadUint64(&s.telemetry.totalBytesDroppedWriter) +} + +func (s *sender) sendLoop() { + defer close(s.stop) + for { + select { + case buffer := <-s.queue: + s.write(buffer) + case <-s.stop: + return + case <-s.flushSignal: + // At that point we know that the workers are paused (the statsd client + // will pause them before calling sender.flush()). + // So we can fully flush the input queue + s.flushInputQueue() + s.flushSignal <- struct{}{} + } + } +} + +func (s *sender) flushInputQueue() { + for { + select { + case buffer := <-s.queue: + s.write(buffer) + default: + return + } + } +} +func (s *sender) flush() { + s.flushSignal <- struct{}{} + <-s.flushSignal +} + +func (s *sender) close() error { + s.stop <- struct{}{} + <-s.stop + s.flushInputQueue() + return s.transport.Close() +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/service_check.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/service_check.go new file mode 100644 index 000000000..e2850465c --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/service_check.go @@ -0,0 +1,57 @@ +package statsd + +import ( + "fmt" + "time" +) + +// ServiceCheckStatus support +type ServiceCheckStatus byte + +const ( + // Ok is the "ok" ServiceCheck status + Ok ServiceCheckStatus = 0 + // Warn is the "warning" ServiceCheck status + Warn ServiceCheckStatus = 1 + // Critical is the "critical" ServiceCheck status + Critical ServiceCheckStatus = 2 + // Unknown is the "unknown" ServiceCheck status + Unknown ServiceCheckStatus = 3 +) + +// A ServiceCheck is an object that contains status of DataDog service check. +type ServiceCheck struct { + // Name of the service check. Required. + Name string + // Status of service check. Required. + Status ServiceCheckStatus + // Timestamp is a timestamp for the serviceCheck. If not provided, the dogstatsd + // server will set this to the current time. + Timestamp time.Time + // Hostname for the serviceCheck. + Hostname string + // A message describing the current state of the serviceCheck. + Message string + // Tags for the serviceCheck. + Tags []string +} + +// NewServiceCheck creates a new serviceCheck with the given name and status. Error checking +// against these values is done at send-time, or upon running sc.Check. +func NewServiceCheck(name string, status ServiceCheckStatus) *ServiceCheck { + return &ServiceCheck{ + Name: name, + Status: status, + } +} + +// Check verifies that a service check is valid. +func (sc *ServiceCheck) Check() error { + if len(sc.Name) == 0 { + return fmt.Errorf("statsd.ServiceCheck name is required") + } + if byte(sc.Status) < 0 || byte(sc.Status) > 3 { + return fmt.Errorf("statsd.ServiceCheck status has invalid value") + } + return nil +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/statsd.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/statsd.go new file mode 100644 index 000000000..378581b9b --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/statsd.go @@ -0,0 +1,838 @@ +// Copyright 2013 Ooyala, Inc. + +/* +Package statsd provides a Go dogstatsd client. Dogstatsd extends the popular statsd, +adding tags and histograms and pushing upstream to Datadog. + +Refer to http://docs.datadoghq.com/guides/dogstatsd/ for information about DogStatsD. + +statsd is based on go-statsd-client. +*/ +package statsd + +//go:generate mockgen -source=statsd.go -destination=mocks/statsd.go + +import ( + "errors" + "fmt" + "io" + "net/url" + "os" + "strconv" + "strings" + "sync" + "sync/atomic" + "time" +) + +/* +OptimalUDPPayloadSize defines the optimal payload size for a UDP datagram, 1432 bytes +is optimal for regular networks with an MTU of 1500 so datagrams don't get +fragmented. It's generally recommended not to fragment UDP datagrams as losing +a single fragment will cause the entire datagram to be lost. +*/ +const OptimalUDPPayloadSize = 1432 + +/* +MaxUDPPayloadSize defines the maximum payload size for a UDP datagram. +Its value comes from the calculation: 65535 bytes Max UDP datagram size - +8byte UDP header - 60byte max IP headers +any number greater than that will see frames being cut out. +*/ +const MaxUDPPayloadSize = 65467 + +// DefaultUDPBufferPoolSize is the default size of the buffer pool for UDP clients. +const DefaultUDPBufferPoolSize = 2048 + +// DefaultUDSBufferPoolSize is the default size of the buffer pool for UDS clients. +const DefaultUDSBufferPoolSize = 512 + +/* +DefaultMaxAgentPayloadSize is the default maximum payload size the agent +can receive. This can be adjusted by changing dogstatsd_buffer_size in the +agent configuration file datadog.yaml. This is also used as the optimal payload size +for UDS datagrams. +*/ +const DefaultMaxAgentPayloadSize = 8192 + +/* +UnixAddressPrefix holds the prefix to use to enable Unix Domain Socket +traffic instead of UDP. +*/ +const UnixAddressPrefix = "unix://" + +/* +WindowsPipeAddressPrefix holds the prefix to use to enable Windows Named Pipes +traffic instead of UDP. +*/ +const WindowsPipeAddressPrefix = `\\.\pipe\` + +const ( + agentHostEnvVarName = "DD_AGENT_HOST" + agentPortEnvVarName = "DD_DOGSTATSD_PORT" + agentURLEnvVarName = "DD_DOGSTATSD_URL" + defaultUDPPort = "8125" +) + +const ( + // ddEntityID specifies client-side user-specified entity ID injection. + // This env var can be set to the Pod UID on Kubernetes via the downward API. + // Docs: https://docs.datadoghq.com/developers/dogstatsd/?tab=kubernetes#origin-detection-over-udp + ddEntityID = "DD_ENTITY_ID" + + // ddEntityIDTag specifies the tag name for the client-side entity ID injection + // The Agent expects this tag to contain a non-prefixed Kubernetes Pod UID. + ddEntityIDTag = "dd.internal.entity_id" + + // originDetectionEnabled specifies the env var to enable/disable sending the container ID field. + originDetectionEnabled = "DD_ORIGIN_DETECTION_ENABLED" +) + +/* +ddEnvTagsMapping is a mapping of each "DD_" prefixed environment variable +to a specific tag name. We use a slice to keep the order and simplify tests. +*/ +var ddEnvTagsMapping = []struct{ envName, tagName string }{ + {ddEntityID, ddEntityIDTag}, // Client-side entity ID injection for container tagging. + {"DD_ENV", "env"}, // The name of the env in which the service runs. + {"DD_SERVICE", "service"}, // The name of the running service. + {"DD_VERSION", "version"}, // The current version of the running service. +} + +type metricType int + +const ( + gauge metricType = iota + count + histogram + histogramAggregated + distribution + distributionAggregated + set + timing + timingAggregated + event + serviceCheck +) + +type receivingMode int + +const ( + mutexMode receivingMode = iota + channelMode +) + +const ( + writerNameUDP string = "udp" + writerNameUDS string = "uds" + writerWindowsPipe string = "pipe" +) + +// noTimestamp is used as a value for metric without a given timestamp. +const noTimestamp = int64(0) + +type metric struct { + metricType metricType + namespace string + globalTags []string + name string + fvalue float64 + fvalues []float64 + ivalue int64 + svalue string + evalue *Event + scvalue *ServiceCheck + tags []string + stags string + rate float64 + timestamp int64 +} + +type noClientErr string + +// ErrNoClient is returned if statsd reporting methods are invoked on +// a nil client. +const ErrNoClient = noClientErr("statsd client is nil") + +func (e noClientErr) Error() string { + return string(e) +} + +type invalidTimestampErr string + +// InvalidTimestamp is returned if a provided timestamp is invalid. +const InvalidTimestamp = invalidTimestampErr("invalid timestamp") + +func (e invalidTimestampErr) Error() string { + return string(e) +} + +// ClientInterface is an interface that exposes the common client functions for the +// purpose of being able to provide a no-op client or even mocking. This can aid +// downstream users' with their testing. +type ClientInterface interface { + // Gauge measures the value of a metric at a particular time. + Gauge(name string, value float64, tags []string, rate float64) error + + // GaugeWithTimestamp measures the value of a metric at a given time. + // BETA - Please contact our support team for more information to use this feature: https://www.datadoghq.com/support/ + // The value will bypass any aggregation on the client side and agent side, this is + // useful when sending points in the past. + // + // Minimum Datadog Agent version: 7.40.0 + GaugeWithTimestamp(name string, value float64, tags []string, rate float64, timestamp time.Time) error + + // Count tracks how many times something happened per second. + Count(name string, value int64, tags []string, rate float64) error + + // CountWithTimestamp tracks how many times something happened at the given second. + // BETA - Please contact our support team for more information to use this feature: https://www.datadoghq.com/support/ + // The value will bypass any aggregation on the client side and agent side, this is + // useful when sending points in the past. + // + // Minimum Datadog Agent version: 7.40.0 + CountWithTimestamp(name string, value int64, tags []string, rate float64, timestamp time.Time) error + + // Histogram tracks the statistical distribution of a set of values on each host. + Histogram(name string, value float64, tags []string, rate float64) error + + // Distribution tracks the statistical distribution of a set of values across your infrastructure. + Distribution(name string, value float64, tags []string, rate float64) error + + // Decr is just Count of -1 + Decr(name string, tags []string, rate float64) error + + // Incr is just Count of 1 + Incr(name string, tags []string, rate float64) error + + // Set counts the number of unique elements in a group. + Set(name string, value string, tags []string, rate float64) error + + // Timing sends timing information, it is an alias for TimeInMilliseconds + Timing(name string, value time.Duration, tags []string, rate float64) error + + // TimeInMilliseconds sends timing information in milliseconds. + // It is flushed by statsd with percentiles, mean and other info (https://github.com/etsy/statsd/blob/master/docs/metric_types.md#timing) + TimeInMilliseconds(name string, value float64, tags []string, rate float64) error + + // Event sends the provided Event. + Event(e *Event) error + + // SimpleEvent sends an event with the provided title and text. + SimpleEvent(title, text string) error + + // ServiceCheck sends the provided ServiceCheck. + ServiceCheck(sc *ServiceCheck) error + + // SimpleServiceCheck sends an serviceCheck with the provided name and status. + SimpleServiceCheck(name string, status ServiceCheckStatus) error + + // Close the client connection. + Close() error + + // Flush forces a flush of all the queued dogstatsd payloads. + Flush() error + + // IsClosed returns if the client has been closed. + IsClosed() bool + + // GetTelemetry return the telemetry metrics for the client since it started. + GetTelemetry() Telemetry +} + +// A Client is a handle for sending messages to dogstatsd. It is safe to +// use one Client from multiple goroutines simultaneously. +type Client struct { + // Sender handles the underlying networking protocol + sender *sender + // namespace to prepend to all statsd calls + namespace string + // tags are global tags to be added to every statsd call + tags []string + flushTime time.Duration + telemetry *statsdTelemetry + telemetryClient *telemetryClient + stop chan struct{} + wg sync.WaitGroup + workers []*worker + closerLock sync.Mutex + workersMode receivingMode + aggregatorMode receivingMode + agg *aggregator + aggExtended *aggregator + options []Option + addrOption string + isClosed bool +} + +// statsdTelemetry contains telemetry metrics about the client +type statsdTelemetry struct { + totalMetricsGauge uint64 + totalMetricsCount uint64 + totalMetricsHistogram uint64 + totalMetricsDistribution uint64 + totalMetricsSet uint64 + totalMetricsTiming uint64 + totalEvents uint64 + totalServiceChecks uint64 + totalDroppedOnReceive uint64 +} + +// Verify that Client implements the ClientInterface. +// https://golang.org/doc/faq#guarantee_satisfies_interface +var _ ClientInterface = &Client{} + +func resolveAddr(addr string) string { + envPort := "" + + if addr == "" { + addr = os.Getenv(agentHostEnvVarName) + envPort = os.Getenv(agentPortEnvVarName) + agentURL, _ := os.LookupEnv(agentURLEnvVarName) + agentURL = parseAgentURL(agentURL) + + // agentURLEnvVarName has priority over agentHostEnvVarName + if agentURL != "" { + return agentURL + } + } + + if addr == "" { + return "" + } + + if !strings.HasPrefix(addr, WindowsPipeAddressPrefix) && !strings.HasPrefix(addr, UnixAddressPrefix) { + if !strings.Contains(addr, ":") { + if envPort != "" { + addr = fmt.Sprintf("%s:%s", addr, envPort) + } else { + addr = fmt.Sprintf("%s:%s", addr, defaultUDPPort) + } + } + } + return addr +} + +func parseAgentURL(agentURL string) string { + if agentURL != "" { + if strings.HasPrefix(agentURL, WindowsPipeAddressPrefix) { + return agentURL + } + + parsedURL, err := url.Parse(agentURL) + if err != nil { + return "" + } + + if parsedURL.Scheme == "udp" { + if strings.Contains(parsedURL.Host, ":") { + return parsedURL.Host + } + return fmt.Sprintf("%s:%s", parsedURL.Host, defaultUDPPort) + } + + if parsedURL.Scheme == "unix" { + return agentURL + } + } + return "" +} + +func createWriter(addr string, writeTimeout time.Duration) (io.WriteCloser, string, error) { + addr = resolveAddr(addr) + if addr == "" { + return nil, "", errors.New("No address passed and autodetection from environment failed") + } + + switch { + case strings.HasPrefix(addr, WindowsPipeAddressPrefix): + w, err := newWindowsPipeWriter(addr, writeTimeout) + return w, writerWindowsPipe, err + case strings.HasPrefix(addr, UnixAddressPrefix): + w, err := newUDSWriter(addr[len(UnixAddressPrefix):], writeTimeout) + return w, writerNameUDS, err + default: + w, err := newUDPWriter(addr, writeTimeout) + return w, writerNameUDP, err + } +} + +// New returns a pointer to a new Client given an addr in the format "hostname:port" for UDP, +// "unix:///path/to/socket" for UDS or "\\.\pipe\path\to\pipe" for Windows Named Pipes. +func New(addr string, options ...Option) (*Client, error) { + o, err := resolveOptions(options) + if err != nil { + return nil, err + } + + w, writerType, err := createWriter(addr, o.writeTimeout) + if err != nil { + return nil, err + } + + client, err := newWithWriter(w, o, writerType) + if err == nil { + client.options = append(client.options, options...) + client.addrOption = addr + } + return client, err +} + +// NewWithWriter creates a new Client with given writer. Writer is a +// io.WriteCloser +func NewWithWriter(w io.WriteCloser, options ...Option) (*Client, error) { + o, err := resolveOptions(options) + if err != nil { + return nil, err + } + return newWithWriter(w, o, "custom") +} + +// CloneWithExtraOptions create a new Client with extra options +func CloneWithExtraOptions(c *Client, options ...Option) (*Client, error) { + if c == nil { + return nil, ErrNoClient + } + + if c.addrOption == "" { + return nil, fmt.Errorf("can't clone client with no addrOption") + } + opt := append(c.options, options...) + return New(c.addrOption, opt...) +} + +func newWithWriter(w io.WriteCloser, o *Options, writerName string) (*Client, error) { + c := Client{ + namespace: o.namespace, + tags: o.tags, + telemetry: &statsdTelemetry{}, + } + + hasEntityID := false + // Inject values of DD_* environment variables as global tags. + for _, mapping := range ddEnvTagsMapping { + if value := os.Getenv(mapping.envName); value != "" { + if mapping.envName == ddEntityID { + hasEntityID = true + } + c.tags = append(c.tags, fmt.Sprintf("%s:%s", mapping.tagName, value)) + } + } + + if !hasEntityID { + initContainerID(o.containerID, isOriginDetectionEnabled(o, hasEntityID)) + } + + if o.maxBytesPerPayload == 0 { + if writerName == writerNameUDS { + o.maxBytesPerPayload = DefaultMaxAgentPayloadSize + } else { + o.maxBytesPerPayload = OptimalUDPPayloadSize + } + } + if o.bufferPoolSize == 0 { + if writerName == writerNameUDS { + o.bufferPoolSize = DefaultUDSBufferPoolSize + } else { + o.bufferPoolSize = DefaultUDPBufferPoolSize + } + } + if o.senderQueueSize == 0 { + if writerName == writerNameUDS { + o.senderQueueSize = DefaultUDSBufferPoolSize + } else { + o.senderQueueSize = DefaultUDPBufferPoolSize + } + } + + bufferPool := newBufferPool(o.bufferPoolSize, o.maxBytesPerPayload, o.maxMessagesPerPayload) + c.sender = newSender(w, o.senderQueueSize, bufferPool) + c.aggregatorMode = o.receiveMode + + c.workersMode = o.receiveMode + // channelMode mode at the worker level is not enabled when + // ExtendedAggregation is since the user app will not directly + // use the worker (the aggregator sit between the app and the + // workers). + if o.extendedAggregation { + c.workersMode = mutexMode + } + + if o.aggregation || o.extendedAggregation { + c.agg = newAggregator(&c) + c.agg.start(o.aggregationFlushInterval) + + if o.extendedAggregation { + c.aggExtended = c.agg + + if c.aggregatorMode == channelMode { + c.agg.startReceivingMetric(o.channelModeBufferSize, o.workersCount) + } + } + } + + for i := 0; i < o.workersCount; i++ { + w := newWorker(bufferPool, c.sender) + c.workers = append(c.workers, w) + + if c.workersMode == channelMode { + w.startReceivingMetric(o.channelModeBufferSize) + } + } + + c.flushTime = o.bufferFlushInterval + c.stop = make(chan struct{}, 1) + + c.wg.Add(1) + go func() { + defer c.wg.Done() + c.watch() + }() + + if o.telemetry { + if o.telemetryAddr == "" { + c.telemetryClient = newTelemetryClient(&c, writerName, c.agg != nil) + } else { + var err error + c.telemetryClient, err = newTelemetryClientWithCustomAddr(&c, writerName, o.telemetryAddr, c.agg != nil, bufferPool, o.writeTimeout) + if err != nil { + return nil, err + } + } + c.telemetryClient.run(&c.wg, c.stop) + } + + return &c, nil +} + +func (c *Client) watch() { + ticker := time.NewTicker(c.flushTime) + + for { + select { + case <-ticker.C: + for _, w := range c.workers { + w.flush() + } + case <-c.stop: + ticker.Stop() + return + } + } +} + +// Flush forces a flush of all the queued dogstatsd payloads This method is +// blocking and will not return until everything is sent through the network. +// In mutexMode, this will also block sampling new data to the client while the +// workers and sender are flushed. +func (c *Client) Flush() error { + if c == nil { + return ErrNoClient + } + if c.agg != nil { + c.agg.flush() + } + for _, w := range c.workers { + w.pause() + defer w.unpause() + w.flushUnsafe() + } + // Now that the worker are pause the sender can flush the queue between + // worker and senders + c.sender.flush() + return nil +} + +// IsClosed returns if the client has been closed. +func (c *Client) IsClosed() bool { + c.closerLock.Lock() + defer c.closerLock.Unlock() + return c.isClosed +} + +func (c *Client) flushTelemetryMetrics(t *Telemetry) { + t.TotalMetricsGauge = atomic.LoadUint64(&c.telemetry.totalMetricsGauge) + t.TotalMetricsCount = atomic.LoadUint64(&c.telemetry.totalMetricsCount) + t.TotalMetricsSet = atomic.LoadUint64(&c.telemetry.totalMetricsSet) + t.TotalMetricsHistogram = atomic.LoadUint64(&c.telemetry.totalMetricsHistogram) + t.TotalMetricsDistribution = atomic.LoadUint64(&c.telemetry.totalMetricsDistribution) + t.TotalMetricsTiming = atomic.LoadUint64(&c.telemetry.totalMetricsTiming) + t.TotalEvents = atomic.LoadUint64(&c.telemetry.totalEvents) + t.TotalServiceChecks = atomic.LoadUint64(&c.telemetry.totalServiceChecks) + t.TotalDroppedOnReceive = atomic.LoadUint64(&c.telemetry.totalDroppedOnReceive) +} + +// GetTelemetry return the telemetry metrics for the client since it started. +func (c *Client) GetTelemetry() Telemetry { + return c.telemetryClient.getTelemetry() +} + +func (c *Client) send(m metric) error { + h := hashString32(m.name) + worker := c.workers[h%uint32(len(c.workers))] + + if c.workersMode == channelMode { + select { + case worker.inputMetrics <- m: + default: + atomic.AddUint64(&c.telemetry.totalDroppedOnReceive, 1) + } + return nil + } + return worker.processMetric(m) +} + +// sendBlocking is used by the aggregator to inject aggregated metrics. +func (c *Client) sendBlocking(m metric) error { + m.globalTags = c.tags + m.namespace = c.namespace + + h := hashString32(m.name) + worker := c.workers[h%uint32(len(c.workers))] + return worker.processMetric(m) +} + +func (c *Client) sendToAggregator(mType metricType, name string, value float64, tags []string, rate float64, f bufferedMetricSampleFunc) error { + if c.aggregatorMode == channelMode { + select { + case c.aggExtended.inputMetrics <- metric{metricType: mType, name: name, fvalue: value, tags: tags, rate: rate}: + default: + atomic.AddUint64(&c.telemetry.totalDroppedOnReceive, 1) + } + return nil + } + return f(name, value, tags, rate) +} + +// Gauge measures the value of a metric at a particular time. +func (c *Client) Gauge(name string, value float64, tags []string, rate float64) error { + if c == nil { + return ErrNoClient + } + atomic.AddUint64(&c.telemetry.totalMetricsGauge, 1) + if c.agg != nil { + return c.agg.gauge(name, value, tags) + } + return c.send(metric{metricType: gauge, name: name, fvalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace}) +} + +// GaugeWithTimestamp measures the value of a metric at a given time. +// BETA - Please contact our support team for more information to use this feature: https://www.datadoghq.com/support/ +// The value will bypass any aggregation on the client side and agent side, this is +// useful when sending points in the past. +// +// Minimum Datadog Agent version: 7.40.0 +func (c *Client) GaugeWithTimestamp(name string, value float64, tags []string, rate float64, timestamp time.Time) error { + if c == nil { + return ErrNoClient + } + + if timestamp.IsZero() || timestamp.Unix() <= noTimestamp { + return InvalidTimestamp + } + + atomic.AddUint64(&c.telemetry.totalMetricsGauge, 1) + return c.send(metric{metricType: gauge, name: name, fvalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace, timestamp: timestamp.Unix()}) +} + +// Count tracks how many times something happened per second. +func (c *Client) Count(name string, value int64, tags []string, rate float64) error { + if c == nil { + return ErrNoClient + } + atomic.AddUint64(&c.telemetry.totalMetricsCount, 1) + if c.agg != nil { + return c.agg.count(name, value, tags) + } + return c.send(metric{metricType: count, name: name, ivalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace}) +} + +// CountWithTimestamp tracks how many times something happened at the given second. +// BETA - Please contact our support team for more information to use this feature: https://www.datadoghq.com/support/ +// The value will bypass any aggregation on the client side and agent side, this is +// useful when sending points in the past. +// +// Minimum Datadog Agent version: 7.40.0 +func (c *Client) CountWithTimestamp(name string, value int64, tags []string, rate float64, timestamp time.Time) error { + if c == nil { + return ErrNoClient + } + + if timestamp.IsZero() || timestamp.Unix() <= noTimestamp { + return InvalidTimestamp + } + + atomic.AddUint64(&c.telemetry.totalMetricsCount, 1) + return c.send(metric{metricType: count, name: name, ivalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace, timestamp: timestamp.Unix()}) +} + +// Histogram tracks the statistical distribution of a set of values on each host. +func (c *Client) Histogram(name string, value float64, tags []string, rate float64) error { + if c == nil { + return ErrNoClient + } + atomic.AddUint64(&c.telemetry.totalMetricsHistogram, 1) + if c.aggExtended != nil { + return c.sendToAggregator(histogram, name, value, tags, rate, c.aggExtended.histogram) + } + return c.send(metric{metricType: histogram, name: name, fvalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace}) +} + +// Distribution tracks the statistical distribution of a set of values across your infrastructure. +func (c *Client) Distribution(name string, value float64, tags []string, rate float64) error { + if c == nil { + return ErrNoClient + } + atomic.AddUint64(&c.telemetry.totalMetricsDistribution, 1) + if c.aggExtended != nil { + return c.sendToAggregator(distribution, name, value, tags, rate, c.aggExtended.distribution) + } + return c.send(metric{metricType: distribution, name: name, fvalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace}) +} + +// Decr is just Count of -1 +func (c *Client) Decr(name string, tags []string, rate float64) error { + return c.Count(name, -1, tags, rate) +} + +// Incr is just Count of 1 +func (c *Client) Incr(name string, tags []string, rate float64) error { + return c.Count(name, 1, tags, rate) +} + +// Set counts the number of unique elements in a group. +func (c *Client) Set(name string, value string, tags []string, rate float64) error { + if c == nil { + return ErrNoClient + } + atomic.AddUint64(&c.telemetry.totalMetricsSet, 1) + if c.agg != nil { + return c.agg.set(name, value, tags) + } + return c.send(metric{metricType: set, name: name, svalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace}) +} + +// Timing sends timing information, it is an alias for TimeInMilliseconds +func (c *Client) Timing(name string, value time.Duration, tags []string, rate float64) error { + return c.TimeInMilliseconds(name, value.Seconds()*1000, tags, rate) +} + +// TimeInMilliseconds sends timing information in milliseconds. +// It is flushed by statsd with percentiles, mean and other info (https://github.com/etsy/statsd/blob/master/docs/metric_types.md#timing) +func (c *Client) TimeInMilliseconds(name string, value float64, tags []string, rate float64) error { + if c == nil { + return ErrNoClient + } + atomic.AddUint64(&c.telemetry.totalMetricsTiming, 1) + if c.aggExtended != nil { + return c.sendToAggregator(timing, name, value, tags, rate, c.aggExtended.timing) + } + return c.send(metric{metricType: timing, name: name, fvalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace}) +} + +// Event sends the provided Event. +func (c *Client) Event(e *Event) error { + if c == nil { + return ErrNoClient + } + atomic.AddUint64(&c.telemetry.totalEvents, 1) + return c.send(metric{metricType: event, evalue: e, rate: 1, globalTags: c.tags, namespace: c.namespace}) +} + +// SimpleEvent sends an event with the provided title and text. +func (c *Client) SimpleEvent(title, text string) error { + e := NewEvent(title, text) + return c.Event(e) +} + +// ServiceCheck sends the provided ServiceCheck. +func (c *Client) ServiceCheck(sc *ServiceCheck) error { + if c == nil { + return ErrNoClient + } + atomic.AddUint64(&c.telemetry.totalServiceChecks, 1) + return c.send(metric{metricType: serviceCheck, scvalue: sc, rate: 1, globalTags: c.tags, namespace: c.namespace}) +} + +// SimpleServiceCheck sends an serviceCheck with the provided name and status. +func (c *Client) SimpleServiceCheck(name string, status ServiceCheckStatus) error { + sc := NewServiceCheck(name, status) + return c.ServiceCheck(sc) +} + +// Close the client connection. +func (c *Client) Close() error { + if c == nil { + return ErrNoClient + } + + // Acquire closer lock to ensure only one thread can close the stop channel + c.closerLock.Lock() + defer c.closerLock.Unlock() + + if c.isClosed { + return nil + } + + // Notify all other threads that they should stop + select { + case <-c.stop: + return nil + default: + } + close(c.stop) + + if c.workersMode == channelMode { + for _, w := range c.workers { + w.stopReceivingMetric() + } + } + + // flush the aggregator first + if c.agg != nil { + if c.aggExtended != nil && c.aggregatorMode == channelMode { + c.agg.stopReceivingMetric() + } + c.agg.stop() + } + + // Wait for the threads to stop + c.wg.Wait() + + c.Flush() + + c.isClosed = true + return c.sender.close() +} + +// isOriginDetectionEnabled returns whether the clients should fill the container field. +// +// If DD_ENTITY_ID is set, we don't send the container ID +// If a user-defined container ID is provided, we don't ignore origin detection +// as dd.internal.entity_id is prioritized over the container field for backward compatibility. +// If DD_ENTITY_ID is not set, we try to fill the container field automatically unless +// DD_ORIGIN_DETECTION_ENABLED is explicitly set to false. +func isOriginDetectionEnabled(o *Options, hasEntityID bool) bool { + if !o.originDetection || hasEntityID || o.containerID != "" { + // originDetection is explicitly disabled + // or DD_ENTITY_ID was found + // or a user-defined container ID was provided + return false + } + + envVarValue := os.Getenv(originDetectionEnabled) + if envVarValue == "" { + // DD_ORIGIN_DETECTION_ENABLED is not set + // default to true + return true + } + + enabled, err := strconv.ParseBool(envVarValue) + if err != nil { + // Error due to an unsupported DD_ORIGIN_DETECTION_ENABLED value + // default to true + return true + } + + return enabled +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/telemetry.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/telemetry.go new file mode 100644 index 000000000..1e2bc0a3f --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/telemetry.go @@ -0,0 +1,274 @@ +package statsd + +import ( + "fmt" + "sync" + "time" +) + +/* +telemetryInterval is the interval at which telemetry will be sent by the client. +*/ +const telemetryInterval = 10 * time.Second + +/* +clientTelemetryTag is a tag identifying this specific client. +*/ +var clientTelemetryTag = "client:go" + +/* +clientVersionTelemetryTag is a tag identifying this specific client version. +*/ +var clientVersionTelemetryTag = "client_version:5.3.0" + +// Telemetry represents internal metrics about the client behavior since it started. +type Telemetry struct { + // + // Those are produced by the 'Client' + // + + // TotalMetrics is the total number of metrics sent by the client before aggregation and sampling. + TotalMetrics uint64 + // TotalMetricsGauge is the total number of gauges sent by the client before aggregation and sampling. + TotalMetricsGauge uint64 + // TotalMetricsCount is the total number of counts sent by the client before aggregation and sampling. + TotalMetricsCount uint64 + // TotalMetricsHistogram is the total number of histograms sent by the client before aggregation and sampling. + TotalMetricsHistogram uint64 + // TotalMetricsDistribution is the total number of distributions sent by the client before aggregation and + // sampling. + TotalMetricsDistribution uint64 + // TotalMetricsSet is the total number of sets sent by the client before aggregation and sampling. + TotalMetricsSet uint64 + // TotalMetricsTiming is the total number of timings sent by the client before aggregation and sampling. + TotalMetricsTiming uint64 + // TotalEvents is the total number of events sent by the client before aggregation and sampling. + TotalEvents uint64 + // TotalServiceChecks is the total number of service_checks sent by the client before aggregation and sampling. + TotalServiceChecks uint64 + + // TotalDroppedOnReceive is the total number metrics/event/service_checks dropped when using ChannelMode (see + // WithChannelMode option). + TotalDroppedOnReceive uint64 + + // + // Those are produced by the 'sender' + // + + // TotalPayloadsSent is the total number of payload (packet on the network) succesfully sent by the client. When + // using UDP we don't know if packet dropped or not, so all packet are considered as succesfully sent. + TotalPayloadsSent uint64 + // TotalPayloadsDropped is the total number of payload dropped by the client. This includes all cause of dropped + // (TotalPayloadsDroppedQueueFull and TotalPayloadsDroppedWriter). When using UDP This won't includes the + // network dropped. + TotalPayloadsDropped uint64 + // TotalPayloadsDroppedWriter is the total number of payload dropped by the writer (when using UDS or named + // pipe) due to network timeout or error. + TotalPayloadsDroppedWriter uint64 + // TotalPayloadsDroppedQueueFull is the total number of payload dropped internally because the queue of payloads + // waiting to be sent on the wire is full. This means the client is generating more metrics than can be sent on + // the wire. If your app sends metrics in batch look at WithSenderQueueSize option to increase the queue size. + TotalPayloadsDroppedQueueFull uint64 + + // TotalBytesSent is the total number of bytes succesfully sent by the client. When using UDP we don't know if + // packet dropped or not, so all packet are considered as succesfully sent. + TotalBytesSent uint64 + // TotalBytesDropped is the total number of bytes dropped by the client. This includes all cause of dropped + // (TotalBytesDroppedQueueFull and TotalBytesDroppedWriter). When using UDP This + // won't includes the network dropped. + TotalBytesDropped uint64 + // TotalBytesDroppedWriter is the total number of bytes dropped by the writer (when using UDS or named pipe) due + // to network timeout or error. + TotalBytesDroppedWriter uint64 + // TotalBytesDroppedQueueFull is the total number of bytes dropped internally because the queue of payloads + // waiting to be sent on the wire is full. This means the client is generating more metrics than can be sent on + // the wire. If your app sends metrics in batch look at WithSenderQueueSize option to increase the queue size. + TotalBytesDroppedQueueFull uint64 + + // + // Those are produced by the 'aggregator' + // + + // AggregationNbContext is the total number of contexts flushed by the aggregator when either + // WithClientSideAggregation or WithExtendedClientSideAggregation options are enabled. + AggregationNbContext uint64 + // AggregationNbContextGauge is the total number of contexts for gauges flushed by the aggregator when either + // WithClientSideAggregation or WithExtendedClientSideAggregation options are enabled. + AggregationNbContextGauge uint64 + // AggregationNbContextCount is the total number of contexts for counts flushed by the aggregator when either + // WithClientSideAggregation or WithExtendedClientSideAggregation options are enabled. + AggregationNbContextCount uint64 + // AggregationNbContextSet is the total number of contexts for sets flushed by the aggregator when either + // WithClientSideAggregation or WithExtendedClientSideAggregation options are enabled. + AggregationNbContextSet uint64 + // AggregationNbContextHistogram is the total number of contexts for histograms flushed by the aggregator when either + // WithClientSideAggregation or WithExtendedClientSideAggregation options are enabled. + AggregationNbContextHistogram uint64 + // AggregationNbContextDistribution is the total number of contexts for distributions flushed by the aggregator when either + // WithClientSideAggregation or WithExtendedClientSideAggregation options are enabled. + AggregationNbContextDistribution uint64 + // AggregationNbContextTiming is the total number of contexts for timings flushed by the aggregator when either + // WithClientSideAggregation or WithExtendedClientSideAggregation options are enabled. + AggregationNbContextTiming uint64 +} + +type telemetryClient struct { + c *Client + tags []string + aggEnabled bool // is aggregation enabled and should we sent aggregation telemetry. + tagsByType map[metricType][]string + sender *sender + worker *worker + lastSample Telemetry // The previous sample of telemetry sent +} + +func newTelemetryClient(c *Client, transport string, aggregationEnabled bool) *telemetryClient { + t := &telemetryClient{ + c: c, + tags: append(c.tags, clientTelemetryTag, clientVersionTelemetryTag, "client_transport:"+transport), + aggEnabled: aggregationEnabled, + tagsByType: map[metricType][]string{}, + } + + t.tagsByType[gauge] = append(append([]string{}, t.tags...), "metrics_type:gauge") + t.tagsByType[count] = append(append([]string{}, t.tags...), "metrics_type:count") + t.tagsByType[set] = append(append([]string{}, t.tags...), "metrics_type:set") + t.tagsByType[timing] = append(append([]string{}, t.tags...), "metrics_type:timing") + t.tagsByType[histogram] = append(append([]string{}, t.tags...), "metrics_type:histogram") + t.tagsByType[distribution] = append(append([]string{}, t.tags...), "metrics_type:distribution") + return t +} + +func newTelemetryClientWithCustomAddr(c *Client, transport string, telemetryAddr string, aggregationEnabled bool, pool *bufferPool, writeTimeout time.Duration) (*telemetryClient, error) { + telemetryWriter, _, err := createWriter(telemetryAddr, writeTimeout) + if err != nil { + return nil, fmt.Errorf("Could not resolve telemetry address: %v", err) + } + + t := newTelemetryClient(c, transport, aggregationEnabled) + + // Creating a custom sender/worker with 1 worker in mutex mode for the + // telemetry that share the same bufferPool. + // FIXME due to performance pitfall, we're always using UDP defaults + // even for UDS. + t.sender = newSender(telemetryWriter, DefaultUDPBufferPoolSize, pool) + t.worker = newWorker(pool, t.sender) + return t, nil +} + +func (t *telemetryClient) run(wg *sync.WaitGroup, stop chan struct{}) { + wg.Add(1) + go func() { + defer wg.Done() + ticker := time.NewTicker(telemetryInterval) + for { + select { + case <-ticker.C: + t.sendTelemetry() + case <-stop: + ticker.Stop() + if t.sender != nil { + t.sender.close() + } + return + } + } + }() +} + +func (t *telemetryClient) sendTelemetry() { + for _, m := range t.flush() { + if t.worker != nil { + t.worker.processMetric(m) + } else { + t.c.send(m) + } + } + + if t.worker != nil { + t.worker.flush() + } +} + +func (t *telemetryClient) getTelemetry() Telemetry { + if t == nil { + // telemetry was disabled through the WithoutTelemetry option + return Telemetry{} + } + + tlm := Telemetry{} + t.c.flushTelemetryMetrics(&tlm) + t.c.sender.flushTelemetryMetrics(&tlm) + t.c.agg.flushTelemetryMetrics(&tlm) + + tlm.TotalMetrics = tlm.TotalMetricsGauge + + tlm.TotalMetricsCount + + tlm.TotalMetricsSet + + tlm.TotalMetricsHistogram + + tlm.TotalMetricsDistribution + + tlm.TotalMetricsTiming + + tlm.TotalPayloadsDropped = tlm.TotalPayloadsDroppedQueueFull + tlm.TotalPayloadsDroppedWriter + tlm.TotalBytesDropped = tlm.TotalBytesDroppedQueueFull + tlm.TotalBytesDroppedWriter + + if t.aggEnabled { + tlm.AggregationNbContext = tlm.AggregationNbContextGauge + + tlm.AggregationNbContextCount + + tlm.AggregationNbContextSet + + tlm.AggregationNbContextHistogram + + tlm.AggregationNbContextDistribution + + tlm.AggregationNbContextTiming + } + return tlm +} + +// flushTelemetry returns Telemetry metrics to be flushed. It's its own function to ease testing. +func (t *telemetryClient) flush() []metric { + m := []metric{} + + // same as Count but without global namespace + telemetryCount := func(name string, value int64, tags []string) { + m = append(m, metric{metricType: count, name: name, ivalue: value, tags: tags, rate: 1}) + } + + tlm := t.getTelemetry() + + // We send the diff between now and the previous telemetry flush. This keep the same telemetry behavior from V4 + // so users dashboard's aren't broken when upgrading to V5. It also allow to graph on the same dashboard a mix + // of V4 and V5 apps. + telemetryCount("datadog.dogstatsd.client.metrics", int64(tlm.TotalMetrics-t.lastSample.TotalMetrics), t.tags) + telemetryCount("datadog.dogstatsd.client.metrics_by_type", int64(tlm.TotalMetricsGauge-t.lastSample.TotalMetricsGauge), t.tagsByType[gauge]) + telemetryCount("datadog.dogstatsd.client.metrics_by_type", int64(tlm.TotalMetricsCount-t.lastSample.TotalMetricsCount), t.tagsByType[count]) + telemetryCount("datadog.dogstatsd.client.metrics_by_type", int64(tlm.TotalMetricsHistogram-t.lastSample.TotalMetricsHistogram), t.tagsByType[histogram]) + telemetryCount("datadog.dogstatsd.client.metrics_by_type", int64(tlm.TotalMetricsDistribution-t.lastSample.TotalMetricsDistribution), t.tagsByType[distribution]) + telemetryCount("datadog.dogstatsd.client.metrics_by_type", int64(tlm.TotalMetricsSet-t.lastSample.TotalMetricsSet), t.tagsByType[set]) + telemetryCount("datadog.dogstatsd.client.metrics_by_type", int64(tlm.TotalMetricsTiming-t.lastSample.TotalMetricsTiming), t.tagsByType[timing]) + telemetryCount("datadog.dogstatsd.client.events", int64(tlm.TotalEvents-t.lastSample.TotalEvents), t.tags) + telemetryCount("datadog.dogstatsd.client.service_checks", int64(tlm.TotalServiceChecks-t.lastSample.TotalServiceChecks), t.tags) + + telemetryCount("datadog.dogstatsd.client.metric_dropped_on_receive", int64(tlm.TotalDroppedOnReceive-t.lastSample.TotalDroppedOnReceive), t.tags) + + telemetryCount("datadog.dogstatsd.client.packets_sent", int64(tlm.TotalPayloadsSent-t.lastSample.TotalPayloadsSent), t.tags) + telemetryCount("datadog.dogstatsd.client.packets_dropped", int64(tlm.TotalPayloadsDropped-t.lastSample.TotalPayloadsDropped), t.tags) + telemetryCount("datadog.dogstatsd.client.packets_dropped_queue", int64(tlm.TotalPayloadsDroppedQueueFull-t.lastSample.TotalPayloadsDroppedQueueFull), t.tags) + telemetryCount("datadog.dogstatsd.client.packets_dropped_writer", int64(tlm.TotalPayloadsDroppedWriter-t.lastSample.TotalPayloadsDroppedWriter), t.tags) + + telemetryCount("datadog.dogstatsd.client.bytes_dropped", int64(tlm.TotalBytesDropped-t.lastSample.TotalBytesDropped), t.tags) + telemetryCount("datadog.dogstatsd.client.bytes_sent", int64(tlm.TotalBytesSent-t.lastSample.TotalBytesSent), t.tags) + telemetryCount("datadog.dogstatsd.client.bytes_dropped_queue", int64(tlm.TotalBytesDroppedQueueFull-t.lastSample.TotalBytesDroppedQueueFull), t.tags) + telemetryCount("datadog.dogstatsd.client.bytes_dropped_writer", int64(tlm.TotalBytesDroppedWriter-t.lastSample.TotalBytesDroppedWriter), t.tags) + + if t.aggEnabled { + telemetryCount("datadog.dogstatsd.client.aggregated_context", int64(tlm.AggregationNbContext-t.lastSample.AggregationNbContext), t.tags) + telemetryCount("datadog.dogstatsd.client.aggregated_context_by_type", int64(tlm.AggregationNbContextGauge-t.lastSample.AggregationNbContextGauge), t.tagsByType[gauge]) + telemetryCount("datadog.dogstatsd.client.aggregated_context_by_type", int64(tlm.AggregationNbContextSet-t.lastSample.AggregationNbContextSet), t.tagsByType[set]) + telemetryCount("datadog.dogstatsd.client.aggregated_context_by_type", int64(tlm.AggregationNbContextCount-t.lastSample.AggregationNbContextCount), t.tagsByType[count]) + telemetryCount("datadog.dogstatsd.client.aggregated_context_by_type", int64(tlm.AggregationNbContextHistogram-t.lastSample.AggregationNbContextHistogram), t.tagsByType[histogram]) + telemetryCount("datadog.dogstatsd.client.aggregated_context_by_type", int64(tlm.AggregationNbContextDistribution-t.lastSample.AggregationNbContextDistribution), t.tagsByType[distribution]) + telemetryCount("datadog.dogstatsd.client.aggregated_context_by_type", int64(tlm.AggregationNbContextTiming-t.lastSample.AggregationNbContextTiming), t.tagsByType[timing]) + } + + t.lastSample = tlm + + return m +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/udp.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/udp.go new file mode 100644 index 000000000..e2922a911 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/udp.go @@ -0,0 +1,34 @@ +package statsd + +import ( + "net" + "time" +) + +// udpWriter is an internal class wrapping around management of UDP connection +type udpWriter struct { + conn net.Conn +} + +// New returns a pointer to a new udpWriter given an addr in the format "hostname:port". +func newUDPWriter(addr string, _ time.Duration) (*udpWriter, error) { + udpAddr, err := net.ResolveUDPAddr("udp", addr) + if err != nil { + return nil, err + } + conn, err := net.DialUDP("udp", nil, udpAddr) + if err != nil { + return nil, err + } + writer := &udpWriter{conn: conn} + return writer, nil +} + +// Write data to the UDP connection with no error handling +func (w *udpWriter) Write(data []byte) (int, error) { + return w.conn.Write(data) +} + +func (w *udpWriter) Close() error { + return w.conn.Close() +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/uds.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/uds.go new file mode 100644 index 000000000..fa5f5917f --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/uds.go @@ -0,0 +1,88 @@ +// +build !windows + +package statsd + +import ( + "net" + "sync" + "time" +) + +// udsWriter is an internal class wrapping around management of UDS connection +type udsWriter struct { + // Address to send metrics to, needed to allow reconnection on error + addr net.Addr + // Established connection object, or nil if not connected yet + conn net.Conn + // write timeout + writeTimeout time.Duration + sync.RWMutex // used to lock conn / writer can replace it +} + +// newUDSWriter returns a pointer to a new udsWriter given a socket file path as addr. +func newUDSWriter(addr string, writeTimeout time.Duration) (*udsWriter, error) { + udsAddr, err := net.ResolveUnixAddr("unixgram", addr) + if err != nil { + return nil, err + } + // Defer connection to first Write + writer := &udsWriter{addr: udsAddr, conn: nil, writeTimeout: writeTimeout} + return writer, nil +} + +// Write data to the UDS connection with write timeout and minimal error handling: +// create the connection if nil, and destroy it if the statsd server has disconnected +func (w *udsWriter) Write(data []byte) (int, error) { + conn, err := w.ensureConnection() + if err != nil { + return 0, err + } + + conn.SetWriteDeadline(time.Now().Add(w.writeTimeout)) + n, e := conn.Write(data) + + if err, isNetworkErr := e.(net.Error); err != nil && (!isNetworkErr || !err.Temporary()) { + // Statsd server disconnected, retry connecting at next packet + w.unsetConnection() + return 0, e + } + return n, e +} + +func (w *udsWriter) Close() error { + if w.conn != nil { + return w.conn.Close() + } + return nil +} + +func (w *udsWriter) ensureConnection() (net.Conn, error) { + // Check if we've already got a socket we can use + w.RLock() + currentConn := w.conn + w.RUnlock() + + if currentConn != nil { + return currentConn, nil + } + + // Looks like we might need to connect - try again with write locking. + w.Lock() + defer w.Unlock() + if w.conn != nil { + return w.conn, nil + } + + newConn, err := net.Dial(w.addr.Network(), w.addr.String()) + if err != nil { + return nil, err + } + w.conn = newConn + return newConn, nil +} + +func (w *udsWriter) unsetConnection() { + w.Lock() + defer w.Unlock() + w.conn = nil +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/uds_windows.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/uds_windows.go new file mode 100644 index 000000000..077894a33 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/uds_windows.go @@ -0,0 +1,14 @@ +// +build windows + +package statsd + +import ( + "fmt" + "io" + "time" +) + +// newUDSWriter is disabled on Windows as Unix sockets are not available. +func newUDSWriter(_ string, _ time.Duration) (io.WriteCloser, error) { + return nil, fmt.Errorf("Unix socket is not available on Windows") +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/utils.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/utils.go new file mode 100644 index 000000000..8c3ac8426 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/utils.go @@ -0,0 +1,32 @@ +package statsd + +import ( + "math/rand" + "sync" +) + +func shouldSample(rate float64, r *rand.Rand, lock *sync.Mutex) bool { + if rate >= 1 { + return true + } + // sources created by rand.NewSource() (ie. w.random) are not thread safe. + // TODO: use defer once the lowest Go version we support is 1.14 (defer + // has an overhead before that). + lock.Lock() + if r.Float64() > rate { + lock.Unlock() + return false + } + lock.Unlock() + return true +} + +func copySlice(src []string) []string { + if src == nil { + return nil + } + + c := make([]string, len(src)) + copy(c, src) + return c +} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/worker.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/worker.go new file mode 100644 index 000000000..952a9fe36 --- /dev/null +++ b/vendor/github.com/DataDog/datadog-go/v5/statsd/worker.go @@ -0,0 +1,150 @@ +package statsd + +import ( + "math/rand" + "sync" + "time" +) + +type worker struct { + pool *bufferPool + buffer *statsdBuffer + sender *sender + random *rand.Rand + randomLock sync.Mutex + sync.Mutex + + inputMetrics chan metric + stop chan struct{} +} + +func newWorker(pool *bufferPool, sender *sender) *worker { + // Each worker uses its own random source and random lock to prevent + // workers in separate goroutines from contending for the lock on the + // "math/rand" package-global random source (e.g. calls like + // "rand.Float64()" must acquire a shared lock to get the next + // pseudorandom number). + // Note that calling "time.Now().UnixNano()" repeatedly quickly may return + // very similar values. That's fine for seeding the worker-specific random + // source because we just need an evenly distributed stream of float values. + // Do not use this random source for cryptographic randomness. + random := rand.New(rand.NewSource(time.Now().UnixNano())) + return &worker{ + pool: pool, + sender: sender, + buffer: pool.borrowBuffer(), + random: random, + stop: make(chan struct{}), + } +} + +func (w *worker) startReceivingMetric(bufferSize int) { + w.inputMetrics = make(chan metric, bufferSize) + go w.pullMetric() +} + +func (w *worker) stopReceivingMetric() { + w.stop <- struct{}{} +} + +func (w *worker) pullMetric() { + for { + select { + case m := <-w.inputMetrics: + w.processMetric(m) + case <-w.stop: + return + } + } +} + +func (w *worker) processMetric(m metric) error { + if !shouldSample(m.rate, w.random, &w.randomLock) { + return nil + } + w.Lock() + var err error + if err = w.writeMetricUnsafe(m); err == errBufferFull { + w.flushUnsafe() + err = w.writeMetricUnsafe(m) + } + w.Unlock() + return err +} + +func (w *worker) writeAggregatedMetricUnsafe(m metric, metricSymbol []byte, precision int) error { + globalPos := 0 + + // first check how much data we can write to the buffer: + // +3 + len(metricSymbol) because the message will include '||#' before the tags + // +1 for the potential line break at the start of the metric + tagsSize := len(m.stags) + 4 + len(metricSymbol) + for _, t := range m.globalTags { + tagsSize += len(t) + 1 + } + + for { + pos, err := w.buffer.writeAggregated(metricSymbol, m.namespace, m.globalTags, m.name, m.fvalues[globalPos:], m.stags, tagsSize, precision) + if err == errPartialWrite { + // We successfully wrote part of the histogram metrics. + // We flush the current buffer and finish the histogram + // in a new one. + w.flushUnsafe() + globalPos += pos + } else { + return err + } + } +} + +func (w *worker) writeMetricUnsafe(m metric) error { + switch m.metricType { + case gauge: + return w.buffer.writeGauge(m.namespace, m.globalTags, m.name, m.fvalue, m.tags, m.rate, m.timestamp) + case count: + return w.buffer.writeCount(m.namespace, m.globalTags, m.name, m.ivalue, m.tags, m.rate, m.timestamp) + case histogram: + return w.buffer.writeHistogram(m.namespace, m.globalTags, m.name, m.fvalue, m.tags, m.rate) + case distribution: + return w.buffer.writeDistribution(m.namespace, m.globalTags, m.name, m.fvalue, m.tags, m.rate) + case set: + return w.buffer.writeSet(m.namespace, m.globalTags, m.name, m.svalue, m.tags, m.rate) + case timing: + return w.buffer.writeTiming(m.namespace, m.globalTags, m.name, m.fvalue, m.tags, m.rate) + case event: + return w.buffer.writeEvent(m.evalue, m.globalTags) + case serviceCheck: + return w.buffer.writeServiceCheck(m.scvalue, m.globalTags) + case histogramAggregated: + return w.writeAggregatedMetricUnsafe(m, histogramSymbol, -1) + case distributionAggregated: + return w.writeAggregatedMetricUnsafe(m, distributionSymbol, -1) + case timingAggregated: + return w.writeAggregatedMetricUnsafe(m, timingSymbol, 6) + default: + return nil + } +} + +func (w *worker) flush() { + w.Lock() + w.flushUnsafe() + w.Unlock() +} + +func (w *worker) pause() { + w.Lock() +} + +func (w *worker) unpause() { + w.Unlock() +} + +// flush the current buffer. Lock must be held by caller. +// flushed buffer written to the network asynchronously. +func (w *worker) flushUnsafe() { + if len(w.buffer.bytes()) > 0 { + w.sender.send(w.buffer) + w.buffer = w.pool.borrowBuffer() + } +} diff --git a/vendor/github.com/DataDog/go-libddwaf/.gitattributes b/vendor/github.com/DataDog/go-libddwaf/.gitattributes new file mode 100644 index 000000000..003a80079 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/.gitattributes @@ -0,0 +1,3 @@ +*.dylib -diff +*.so -diff +*.a -diff diff --git a/vendor/github.com/DataDog/go-libddwaf/.gitignore b/vendor/github.com/DataDog/go-libddwaf/.gitignore new file mode 100644 index 000000000..95311a668 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/.gitignore @@ -0,0 +1,15 @@ +# Binaries for programs and plugins +*.exe +*.exe~ + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +.vscode/ +.idea/ diff --git a/vendor/github.com/DataDog/go-libddwaf/LICENSE b/vendor/github.com/DataDog/go-libddwaf/LICENSE new file mode 100644 index 000000000..9301dd7ab --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/LICENSE @@ -0,0 +1,200 @@ + 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 2016-present Datadog, Inc. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/DataDog/go-libddwaf/README.md b/vendor/github.com/DataDog/go-libddwaf/README.md new file mode 100644 index 000000000..84cb1f89d --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/README.md @@ -0,0 +1,120 @@ +# go-libddwaf + +This project's goal is to produce a higher level API for the go bindings to [libddwaf](https://github.com/DataDog/libddwaf): DataDog in-app WAF. +It consists of 2 separate entities: the bindings for the calls to libddwaf, and the encoder whose job is to convert _any_ go value to its libddwaf object representation. + +An example usage would be: + +```go +import waf "github.com/DataDog/go-libddwaf" + +//go:embed +var ruleset []byte + +func main() { + var parsedRuleset any + + if err := json.Unmarshal(ruleset, &parsedRuleset); err != nil { + return 1 + } + + wafHandle, err := waf.NewHandle(parsedRuleset, "", "") + if err != nil { + return 1 + } + + defer wafHandle.Close() + + wafCtx := wafHandle.NewContext() + defer wafCtx.Close() + + matches, actions := wafCtx.Run(map[string]any{ + "server.request.path_params": "/rfiinc.txt", + }, time.Minute) +} +``` + +The API documentation details can be found on [pkg.go.dev](https://pkg.go.dev/github.com/DataDog/go-libddwaf). + +Originally this project was only here to provide CGO Wrappers to the calls to libddwaf. +But with the appearance of `ddwaf_object` tree like structure, +but also with the intention to build CGO-less bindings, this project size has grown to be a fully integrated brick in the DataDog tracer structure. +Which in turn made it necessary to document the project, to maintain it in an orderly fashion. + +## Design + +The WAF bindings have multiple moving parts that are necessary to understand: + +- Handle: a object wrapper over the pointer to the C WAF Handle +- Context: a object wrapper over a pointer to the C WAF Context +- Encoder: whose goal is to construct a tree of Waf Objects to send to the WAF +- Allocator: Does all writing and allocation operations for the construction of Waf Objects +- Decoder: Transforms Waf Objects returned from the WAF to usual go objects (e.g. maps, arrays, ...) +- Library: The library which wraps all calls to C code + +```mermaid +flowchart LR + + START:::hidden -->|NewHandle| Handle -->|NewContext| Context + + Context -->|Encode Inputs| Encoder + + Handle -->|Encode Ruleset| Encoder + Handle -->|Init WAF| Library + Context -->|Decode Result| Decoder + + Handle -->|Decode Init Errors| Decoder + + Context -->|Run| Library + Context -->|Store Go References| ContextAllocator + + Encoder -->|Allocate Waf Objects| EncoderAllocator + + EncoderAllocator -->|Copy after each encoding| ContextAllocator + + Library -->|Call C code| libddwaf + + classDef hidden display: none; +``` + +### Allocator + +The cgoRefPool is a pure Go cgoRefPool of `ddwaf_object` C values on the Go memory heap. +the `cgoRefPool` go type is a way to make sure we can safely send go allocated data to the C side of the WAF +The main issue is the following: the `wafObject` uses a C union to store the tree structure of the full object, +union equivalent in go are interfaces and they are not compatible with C unions. The only way to be 100% sure +that the Go `wafObject` struct has the same layout as the C one is to only use primitive types. So the only way to +store a raw pointer is to use the `uintptr` type. But since `uintptr` do not have pointer semantics (and are just +basically integers), we need another structure to store the value as Go pointer because the GC is lurking. That's +where the `cgoRefPool` object comes into play: all new `wafObject` elements are created via this API whose especially +built to make sure there is no gap for the Garbage Collector to exploit. From there, since underlying values of the +`wafObject` are either arrays (for maps, structs and arrays) or string (for all ints, booleans and strings), +we can store 2 slices of arrays and use `runtime.KeepAlive` in each code path to protect them from the GC. + +### Typical call to Run() + +Here is an example of the flow of operations on a simple call to Run(): + +- Encode input data into Waf Objects +- Lock the context mutex until the end of the call +- Call `ddwaf_run` +- Decode the matches and actions + +### CGO-less C Bindings + +The main component used to build C bindings without using CGO is called [purego](https://github.com/ebitengine/purego). The flow of execution on our side is to embed the C shared library using `go:embed`. Then to dump it into a file, load it using `dlopen` and to load the symbols using `dlsym`. And finally to call them. + +⚠️ Keep in mind that **purego only works on linux/darwin for amd64/arm64 and so does go-libddwaf.** + +Another requirement of `libddwaf` is to have a FHS filesystem on your machine and, for linux, to provide `libc.so.6`, `libpthread.so.0` and `libm.so.6`, `libdl.so.2` as dynamic libraries. + +## Contributing usual pitfalls + +- Cannot dlopen twice in the app lifetime on OSX +- `runtime.KeepAlive()` calls are here to prevent the GC from destroying objects too early +- Since there is a stack switch between the go code and the C code, usually the only C stacktrace you will ever get is from gdb +- If a segfault happens during a call to the C code, the goroutine stacktrace which has done the call is the one annotated with `[syscall]`. +- [GoLand](https://www.jetbrains.com/go/) does not support `CGO_ENABLED=0` (as of June 2023) +- Keep in mind that we fully escape the type system. If you send the wrong data it will segfaults in the best cases but not always! +- The structs in `ctypes.go` are here to reproduce the memory layout of the structs in `include/ddwaf.h` because pointer to these structs will be passed directly. +- Do not use `uintptr` as function arguments or results types, coming from `unsafe.Pointer` casts of Go values, because they escape the pointer analysis which can create wrongly optimized code and crash. Pointer arithmetic is of course necessary in such a library but must be kept in the same function scope. diff --git a/vendor/github.com/DataDog/go-libddwaf/cgo_ref_pool.go b/vendor/github.com/DataDog/go-libddwaf/cgo_ref_pool.go new file mode 100644 index 000000000..fccd41c9e --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/cgo_ref_pool.go @@ -0,0 +1,90 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package waf + +import ( + "strconv" +) + +// cgoRefPool is a way to make sure we can safely send go allocated data on the C side of the WAF +// The main issue is the following: the wafObject uses a C union to store the tree structure of the full object, +// union equivalent in go are interfaces and they are not compatible with C unions. The only way to be 100% sure +// that the Go wafObject struct have the same layout as the C one is to only use primitive types. So the only way to +// store a raw pointer is to use the uintptr type. But since uintptr do not have pointer semantics (and are just +// basically integers), we need another structure to store the value as Go pointer because the GC is lurking. That's +// where the cgoRefPool object comes into play: All new wafObject elements are created via this API whose especially +// built to make sure there is no gap for the Garbage Collector to exploit. From there, since underlying values of the +// wafObject are either arrays (for maps, structs and arrays) or string (for all ints, booleans and strings), +// we can store 2 slices of arrays and use runtime.KeepAlive in each code path to protect them from the GC. +type cgoRefPool struct { + stringRefs [][]byte + arrayRefs [][]wafObject +} + +func (refPool *cgoRefPool) append(newRefs cgoRefPool) { + refPool.stringRefs = append(refPool.stringRefs, newRefs.stringRefs...) + refPool.arrayRefs = append(refPool.arrayRefs, newRefs.arrayRefs...) +} + +func (refPool *cgoRefPool) AllocCString(str string) uintptr { + goArray := make([]byte, len(str)+1) + copy(goArray, str) + refPool.stringRefs = append(refPool.stringRefs, goArray) + goArray[len(str)] = 0 // Null termination byte for C strings + + return sliceToUintptr(goArray) +} + +func (refPool *cgoRefPool) AllocWafString(obj *wafObject, str string) { + obj._type = wafStringType + + if len(str) == 0 { + obj.nbEntries = 0 + obj.value = 0 + return + } + + goArray := make([]byte, len(str)) + copy(goArray, str) + refPool.stringRefs = append(refPool.stringRefs, goArray) + + obj.value = sliceToUintptr(goArray) + obj.nbEntries = uint64(len(goArray)) +} + +func (refPool *cgoRefPool) AllocWafArray(obj *wafObject, typ wafObjectType, size uint64) []wafObject { + if typ != wafMapType && typ != wafArrayType { + panic("Cannot allocate this waf object data type as an array: " + strconv.Itoa(int(typ))) + } + + obj._type = typ + obj.nbEntries = size + + // If the array size is zero no need to allocate anything + if size == 0 { + obj.value = 0 + return nil + } + + goArray := make([]wafObject, size) + refPool.arrayRefs = append(refPool.arrayRefs, goArray) + + obj.value = sliceToUintptr(goArray) + return goArray +} + +func (refPool *cgoRefPool) AllocWafMapKey(obj *wafObject, str string) { + if len(str) == 0 { + return + } + + goArray := make([]byte, len(str)) + copy(goArray, str) + refPool.stringRefs = append(refPool.stringRefs, goArray) + + obj.parameterName = sliceToUintptr(goArray) + obj.parameterNameLength = uint64(len(goArray)) +} diff --git a/vendor/github.com/DataDog/go-libddwaf/context.go b/vendor/github.com/DataDog/go-libddwaf/context.go new file mode 100644 index 000000000..8fc632d1c --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/context.go @@ -0,0 +1,155 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package waf + +import ( + "sync" + "time" + + "go.uber.org/atomic" +) + +// Context is a WAF execution context. It allows running the WAF incrementally +// when calling it multiple times to run its rules every time new addresses +// become available. Each request must have its own Context. +type Context struct { + // Instance of the WAF + handle *Handle + cContext wafContext + // cgoRefs is used to retain go references to WafObjects until the context is destroyed. + // As per libddwaf documentation, WAF Objects must be alive during all the context lifetime + cgoRefs cgoRefPool + // Mutex protecting the use of cContext which is not thread-safe and cgoRefs. + mutex sync.Mutex + + // Stats + // Cumulated internal WAF run time - in nanoseconds - for this context. + totalRuntimeNs atomic.Uint64 + // Cumulated overall run time - in nanoseconds - for this context. + totalOverallRuntimeNs atomic.Uint64 + // Cumulated timeout count for this context. + timeoutCount atomic.Uint64 +} + +// NewContext returns a new WAF context of to the given WAF handle. +// A nil value is returned when the WAF handle was released or when the +// WAF context couldn't be created. +// handle. A nil value is returned when the WAF handle can no longer be used +// or the WAF context couldn't be created. +func NewContext(handle *Handle) *Context { + // Handle has been released + if handle.addRefCounter(1) == 0 { + return nil + } + + cContext := wafLib.wafContextInit(handle.cHandle) + if cContext == 0 { + handle.addRefCounter(-1) + return nil + } + + return &Context{handle: handle, cContext: cContext} +} + +// Run encodes the given addressesToData values and runs them against the WAF rules within the given +// timeout value. It returns the matches as a JSON string (usually opaquely used) along with the corresponding +// actions in any. In case of an error, matches and actions can still be returned, for instance in the case of a +// timeout error. Errors can be tested against the RunError type. +func (context *Context) Run(addressesToData map[string]any, timeout time.Duration) (matches []byte, actions []string, err error) { + if len(addressesToData) == 0 { + return + } + + now := time.Now() + defer func() { + dt := time.Since(now) + context.totalOverallRuntimeNs.Add(uint64(dt.Nanoseconds())) + }() + + encoder := encoder{ + stringMaxSize: wafMaxStringLength, + containerMaxSize: wafMaxContainerSize, + objectMaxDepth: wafMaxContainerDepth, + } + obj, err := encoder.Encode(addressesToData) + if err != nil { + return nil, nil, err + } + + // ddwaf_run cannot run concurrently and the next append write on the context state so we need a mutex + context.mutex.Lock() + defer context.mutex.Unlock() + + // Save the Go pointer references to addressesToData that were referenced by the encoder + // into C ddwaf_objects. libddwaf's API requires to keep this data for the lifetime of the ddwaf_context. + defer context.cgoRefs.append(encoder.cgoRefs) + + return context.run(obj, timeout, &encoder.cgoRefs) +} + +func (context *Context) run(obj *wafObject, timeout time.Duration, cgoRefs *cgoRefPool) ([]byte, []string, error) { + // RLock the handle to safely get read access to the WAF handle and prevent concurrent changes of it + // such as a rules-data update. + context.handle.mutex.RLock() + defer context.handle.mutex.RUnlock() + + result := new(wafResult) + defer wafLib.wafResultFree(result) + + ret := wafLib.wafRun(context.cContext, obj, result, uint64(timeout/time.Microsecond)) + + context.totalRuntimeNs.Add(result.total_runtime) + matches, actions, err := unwrapWafResult(ret, result) + if err == ErrTimeout { + context.timeoutCount.Inc() + } + + return matches, actions, err +} + +func unwrapWafResult(ret wafReturnCode, result *wafResult) (matches []byte, actions []string, err error) { + if result.timeout > 0 { + err = ErrTimeout + } + + if ret == wafOK { + return nil, nil, err + } + + if ret != wafMatch { + return nil, nil, goRunError(ret) + } + + if result.data != 0 { + matches = []byte(gostring(cast[byte](result.data))) + } + + if size := result.actions.size; size > 0 { + actions = decodeActions(result.actions.array, uint64(size)) + } + + return matches, actions, err +} + +// Close calls handle.closeContext which calls ddwaf_context_destroy and maybe also close the handle if it in termination state. +func (context *Context) Close() { + defer context.handle.closeContext(context) + // Keep the Go pointer references until the end of the context + keepAlive(context.cgoRefs) + // The context is no longer used so we can try releasing the Go pointer references asap by nulling them + context.cgoRefs = cgoRefPool{} +} + +// TotalRuntime returns the cumulated WAF runtime across various run calls within the same WAF context. +// Returned time is in nanoseconds. +func (context *Context) TotalRuntime() (overallRuntimeNs, internalRuntimeNs uint64) { + return context.totalOverallRuntimeNs.Load(), context.totalRuntimeNs.Load() +} + +// TotalTimeouts returns the cumulated amount of WAF timeouts across various run calls within the same WAF context. +func (context *Context) TotalTimeouts() uint64 { + return context.timeoutCount.Load() +} diff --git a/vendor/github.com/DataDog/go-libddwaf/ctypes.go b/vendor/github.com/DataDog/go-libddwaf/ctypes.go new file mode 100644 index 000000000..f5ab1ea26 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/ctypes.go @@ -0,0 +1,176 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package waf + +import ( + "reflect" + "unsafe" +) + +const ( + wafMaxStringLength = 4096 + wafMaxContainerDepth = 20 + wafMaxContainerSize = 256 + wafRunTimeout = 5000 +) + +type wafReturnCode int32 + +const ( + wafErrInternal wafReturnCode = -3 + wafErrInvalidObject = -2 + wafErrInvalidArgument = -1 + wafOK = 0 + wafMatch = 1 +) + +// wafObjectType is an enum in C which has the size of DWORD. +// But DWORD is 4 bytes in amd64 and arm64 so uint32 it is. +type wafObjectType uint32 + +const ( + wafInvalidType wafObjectType = 0 + wafIntType = 1 << 0 + wafUintType = 1 << 1 + wafStringType = 1 << 2 + wafArrayType = 1 << 3 + wafMapType = 1 << 4 +) + +type wafObject struct { + parameterName uintptr + parameterNameLength uint64 + value uintptr + nbEntries uint64 + _type wafObjectType + _ [4]byte + // Forced padding + // We only support 2 archs and cgo generated the same padding to both. + // We don't want the C struct to be packed because actually go will do the same padding itself, + // we just add it explicitly to not take any chance. + // And we cannot pack a struct in go so it will get tricky if the struct is + // packed (apart from breaking all tracers of course) +} + +type wafConfig struct { + limits wafConfigLimits + obfuscator wafConfigObfuscator + freeFn uintptr +} + +type wafConfigLimits struct { + maxContainerSize uint32 + maxContainerDepth uint32 + maxStringLength uint32 +} + +type wafConfigObfuscator struct { + keyRegex uintptr // char * + valueRegex uintptr // char * +} + +type wafResult struct { + timeout byte + data uintptr + actions wafResultActions + total_runtime uint64 +} + +type wafResultActions struct { + array uintptr // char ** + size uint32 + _ [4]byte // Forced padding +} + +type wafRulesetInfo struct { + loaded uint16 + failed uint16 + errors wafObject + version uintptr // char * +} + +// wafHandle is a forward declaration in ddwaf.h header +// We basically don't need to modify it, only to give it to the waf +type wafHandle uintptr + +// wafContext is a forward declaration in ddwaf.h header +// We basically don't need to modify it, only to give it to the waf +type wafContext uintptr + +// gostring copies a char* to a Go string. +func gostring(ptr *byte) string { + if ptr == nil { + return "" + } + var length int + for { + if *(*byte)(unsafe.Add(unsafe.Pointer(ptr), uintptr(length))) == '\x00' { + break + } + length++ + } + //string builtin copies the slice + return string(unsafe.Slice(ptr, length)) +} + +func gostringSized(ptr *byte, size uint64) string { + if ptr == nil { + return "" + } + return string(unsafe.Slice(ptr, size)) +} + +// cstring converts a go string to *byte that can be passed to C code. +func cstring(name string) *byte { + var b = make([]byte, len(name)+1) + copy(b, name) + return &b[0] +} + +// cast is used to centralize unsafe use C of allocated pointer. +// We take the address and then dereference it to trick go vet from creating a possible misuse of unsafe.Pointer +func cast[T any](ptr uintptr) *T { + return (*T)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr))) +} + +// castWithOffset is the same as cast but adding an offset to the pointer by a multiple of the size +// of the type pointed. +func castWithOffset[T any](ptr uintptr, offset uint64) *T { + return (*T)(unsafe.Add(*(*unsafe.Pointer)(unsafe.Pointer(&ptr)), offset*uint64(unsafe.Sizeof(*new(T))))) +} + +// ptrToUintptr is a helper to centralize of usage of unsafe.Pointer +// do not use this function to cast interfaces +func ptrToUintptr[T any](arg *T) uintptr { + return uintptr(unsafe.Pointer(arg)) +} + +func sliceToUintptr[T any](arg []T) uintptr { + return (*reflect.SliceHeader)(unsafe.Pointer(&arg)).Data +} + +func stringToUintptr(arg string) uintptr { + return (*reflect.StringHeader)(unsafe.Pointer(&arg)).Data +} + +// keepAlive() globals +var ( + alwaysFalse bool + escapeSink any +) + +// keepAlive is a copy of runtime.KeepAlive +// keepAlive has 2 usages: +// - It forces the deallocation of the memory to take place later than expected (just like runtime.KeepAlive) +// - It forces the given argument x to be escaped on the heap by saving it into a global value (Go doesn't provide a standard way to do it as of today) +// It is implemented so that the compiler cannot optimize it. +// +//go:noinline +func keepAlive[T any](x T) { + if alwaysFalse { + escapeSink = x + } +} diff --git a/vendor/github.com/DataDog/go-libddwaf/decoder.go b/vendor/github.com/DataDog/go-libddwaf/decoder.go new file mode 100644 index 000000000..b87702539 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/decoder.go @@ -0,0 +1,73 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package waf + +// decodeErrors transforms the wafObject received by the wafRulesetInfo after the call to wafDl.wafInit to a map where +// keys are the error message and the value is a array of all the rule ids which triggered this specific error +func decodeErrors(obj *wafObject) (map[string][]string, error) { + if obj._type != wafMapType { + return nil, errInvalidObjectType + } + + if obj.value == 0 && obj.nbEntries > 0 { + return nil, errNilObjectPtr + } + + wafErrors := map[string][]string{} + for i := uint64(0); i < obj.nbEntries; i++ { + objElem := castWithOffset[wafObject](obj.value, i) + if objElem._type != wafArrayType { + return nil, errInvalidObjectType + } + + errorMessage := gostringSized(cast[byte](objElem.parameterName), objElem.parameterNameLength) + ruleIds, err := decodeRuleIdArray(objElem) + if err != nil { + return nil, err + } + + wafErrors[errorMessage] = ruleIds + } + + return wafErrors, nil +} + +func decodeRuleIdArray(obj *wafObject) ([]string, error) { + if obj._type != wafArrayType { + return nil, errInvalidObjectType + } + + if obj.value == 0 && obj.nbEntries > 0 { + return nil, errNilObjectPtr + } + + var ruleIds []string + for i := uint64(0); i < obj.nbEntries; i++ { + objElem := castWithOffset[wafObject](obj.value, i) + if objElem._type != wafStringType { + return nil, errInvalidObjectType + } + + ruleIds = append(ruleIds, gostringSized(cast[byte](objElem.value), objElem.nbEntries)) + } + + return ruleIds, nil +} + +func decodeActions(cActions uintptr, size uint64) []string { + if size == 0 { + return nil + } + + actions := make([]string, size) + for i := uint64(0); i < size; i++ { + // This line does the following operation without casts: + // gostring(*(cActions + i * sizeof(ptr))) + actions[i] = gostring(*castWithOffset[*byte](cActions, i)) + } + + return actions +} diff --git a/vendor/github.com/DataDog/go-libddwaf/embed_darwin_amd64.go b/vendor/github.com/DataDog/go-libddwaf/embed_darwin_amd64.go new file mode 100644 index 000000000..272d90c90 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/embed_darwin_amd64.go @@ -0,0 +1,13 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build darwin && amd64 && !go1.22 + +package waf + +import _ "embed" // Needed for go:embed + +//go:embed lib/darwin-amd64/_libddwaf.dylib +var libddwaf []byte diff --git a/vendor/github.com/DataDog/go-libddwaf/embed_darwin_arm64.go b/vendor/github.com/DataDog/go-libddwaf/embed_darwin_arm64.go new file mode 100644 index 000000000..1d3f614bd --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/embed_darwin_arm64.go @@ -0,0 +1,13 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build darwin && arm64 && !go1.22 + +package waf + +import _ "embed" // Needed for go:embed + +//go:embed lib/darwin-arm64/_libddwaf.dylib +var libddwaf []byte diff --git a/vendor/github.com/DataDog/go-libddwaf/embed_linux_amd64.go b/vendor/github.com/DataDog/go-libddwaf/embed_linux_amd64.go new file mode 100644 index 000000000..aea447835 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/embed_linux_amd64.go @@ -0,0 +1,13 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build linux && amd64 && !go1.22 + +package waf + +import _ "embed" // Needed for go:embed + +//go:embed lib/linux-amd64/libddwaf.so +var libddwaf []byte diff --git a/vendor/github.com/DataDog/go-libddwaf/embed_linux_arm64.go b/vendor/github.com/DataDog/go-libddwaf/embed_linux_arm64.go new file mode 100644 index 000000000..bdd2b37b8 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/embed_linux_arm64.go @@ -0,0 +1,13 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build linux && arm64 && !go1.22 + +package waf + +import _ "embed" // Needed for go:embed + +//go:embed lib/linux-arm64/libddwaf.so +var libddwaf []byte diff --git a/vendor/github.com/DataDog/go-libddwaf/encoder.go b/vendor/github.com/DataDog/go-libddwaf/encoder.go new file mode 100644 index 000000000..153c12450 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/encoder.go @@ -0,0 +1,256 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package waf + +import ( + "math" + "reflect" + "strconv" + "strings" + "unicode" +) + +// Encode Go values into wafObjects. Only the subset of Go types representable into wafObjects +// will be encoded while ignoring the rest of it. +// The encoder allocates the memory required for new wafObjects into the Go memory, which must be kept +// referenced for their lifetime in the C world. This lifetime depends on the ddwaf function being used with. +// the encoded result. The Go references of the allocated wafObjects, along with every Go pointer they may +// reference now or in the future, are stored and referenced in the `cgoRefs` field. The user MUST leverage +// `keepAlive()` with it according to its ddwaf use-case. +type encoder struct { + containerMaxSize int + stringMaxSize int + objectMaxDepth int + cgoRefs cgoRefPool +} + +func newMaxEncoder() *encoder { + return &encoder{ + containerMaxSize: math.MaxInt, + stringMaxSize: math.MaxInt, + objectMaxDepth: math.MaxInt, + } +} + +func (encoder *encoder) Encode(data any) (*wafObject, error) { + value := reflect.ValueOf(data) + wo := &wafObject{} + + if err := encoder.encode(value, wo, encoder.objectMaxDepth); err != nil { + return nil, err + } + + return wo, nil +} + +func (encoder *encoder) encode(value reflect.Value, obj *wafObject, depth int) error { + switch kind := value.Kind(); { + // Terminal cases (leafs of the tree) + case kind == reflect.Invalid: + return errUnsupportedValue + + // Booleans + case kind == reflect.Bool && value.Bool(): // true + return encoder.encodeString("true", wafStringType, obj) + case kind == reflect.Bool && !value.Bool(): // false + return encoder.encodeString("false", wafStringType, obj) + + // Numbers + case value.CanInt(): // any int type or alias + return encoder.encodeString(strconv.FormatInt(value.Int(), 10), wafStringType, obj) + case value.CanUint(): // any Uint type or alias + return encoder.encodeString(strconv.FormatUint(value.Uint(), 10), wafStringType, obj) + case value.CanFloat(): // any float type or alias + return encoder.encodeString(strconv.FormatInt(int64(math.Round(value.Float())), 10), wafStringType, obj) + + // Strings + case kind == reflect.String: // string type + return encoder.encodeString(value.String(), wafStringType, obj) + case value.Type() == reflect.TypeOf([]byte(nil)): // byte array -> string + return encoder.encodeString(string(value.Bytes()), wafStringType, obj) + + // Recursive cases (internal nodes of the tree) + case kind == reflect.Interface || kind == reflect.Pointer: // Pointer and interfaces are not taken into account + return encoder.encode(value.Elem(), obj, depth) + case kind == reflect.Array || kind == reflect.Slice: // either an array or a slice of an array + return encoder.encodeArray(value, obj, depth) + case kind == reflect.Map: + return encoder.encodeMap(value, obj, depth) + case kind == reflect.Struct: + return encoder.encodeStruct(value, obj, depth) + + default: + return errUnsupportedValue + } +} + +func (encoder *encoder) encodeString(str string, typ wafObjectType, obj *wafObject) error { + if len(str) > encoder.stringMaxSize { + str = str[:encoder.stringMaxSize] + } + + encoder.cgoRefs.AllocWafString(obj, str) + return nil +} + +func getFieldNameFromType(field reflect.StructField) (string, bool) { + fieldName := field.Name + + // Private and synthetics fields + if len(fieldName) < 1 || unicode.IsLower(rune(fieldName[0])) { + return "", false + } + + // Use the json tag name as field name if present + if tag, ok := field.Tag.Lookup("json"); ok { + if i := strings.IndexByte(tag, byte(',')); i > 0 { + tag = tag[:i] + } + if len(tag) > 0 { + fieldName = tag + } + } + + return fieldName, true +} + +// encodeStruct takes a reflect.Value and a wafObject pointer and iterates on the struct field to build +// a wafObject map of type wafMapType. The specificities are the following: +// - It will only take the first encoder.containerMaxSize elements of the struct +// - If the field has a json tag it will become the field name +// - Private fields and also values producing an error at encoding will be skipped +func (encoder *encoder) encodeStruct(value reflect.Value, obj *wafObject, depth int) error { + if depth < 0 { + return errMaxDepth + } + + typ := value.Type() + nbFields := typ.NumField() + capacity := nbFields + length := 0 + if capacity > encoder.containerMaxSize { + capacity = encoder.containerMaxSize + } + + objArray := encoder.cgoRefs.AllocWafArray(obj, wafMapType, uint64(capacity)) + for i := 0; length < capacity && i < nbFields; i++ { + fieldType := typ.Field(i) + fieldName, usable := getFieldNameFromType(fieldType) + if !usable { + continue + } + + objElem := &objArray[length] + if encoder.encodeMapKey(reflect.ValueOf(fieldName), objElem) != nil { + continue + } + + if encoder.encode(value.Field(i), objElem, depth-1) != nil { + continue + } + + length++ + } + + // Set the length to the final number of successfully encoded elements + obj.nbEntries = uint64(length) + return nil +} + +// encodeMap takes a reflect.Value and a wafObject pointer and iterates on the map elements and returns +// a wafObject map of type wafMapType. The specificities are the following: +// - It will only take the first encoder.containerMaxSize elements of the map +// - Values and keys producing an error at encoding will be skipped +func (encoder *encoder) encodeMap(value reflect.Value, obj *wafObject, depth int) error { + if depth < 0 { + return errMaxDepth + } + + capacity := value.Len() + length := 0 + if capacity > encoder.containerMaxSize { + capacity = encoder.containerMaxSize + } + + objArray := encoder.cgoRefs.AllocWafArray(obj, wafMapType, uint64(capacity)) + for iter := value.MapRange(); iter.Next(); { + if length == capacity { + break + } + + objElem := &objArray[length] + if encoder.encodeMapKey(iter.Key(), objElem) != nil { + continue + } + + if encoder.encode(iter.Value(), objElem, depth-1) != nil { + continue + } + + length++ + } + + // Fix the size because we skipped map entries + obj.nbEntries = uint64(length) + return nil +} + +// encodeMapKey takes a reflect.Value and a wafObject and returns a wafObject ready to be considered a map key +// We use the function cgoRefPool.AllocWafMapKey to store the key in the wafObject. But first we need +// to grab the real underlying value by recursing through the pointer and interface values. +func (encoder *encoder) encodeMapKey(value reflect.Value, obj *wafObject) error { + kind := value.Kind() + for ; kind == reflect.Pointer || kind == reflect.Interface; value, kind = value.Elem(), value.Elem().Kind() { + if value.IsNil() { + return errInvalidMapKey + } + } + + if kind != reflect.String && value.Type() != reflect.TypeOf([]byte(nil)) { + return errInvalidMapKey + } + + if value.Type() == reflect.TypeOf([]byte(nil)) { + encoder.cgoRefs.AllocWafMapKey(obj, string(value.Bytes())) + } + + if reflect.String == kind { + encoder.cgoRefs.AllocWafMapKey(obj, value.String()) + } + + return nil +} + +// encodeArray takes a reflect.Value and a wafObject pointer and iterates on the elements and returns +// a wafObject array of type wafArrayType. The specificities are the following: +// - It will only take the first encoder.containerMaxSize elements of the array +// - Values producing an error at encoding will be skipped +func (encoder *encoder) encodeArray(value reflect.Value, obj *wafObject, depth int) error { + if depth < 0 { + return errMaxDepth + } + + length := value.Len() + capacity := length + if capacity > encoder.containerMaxSize { + capacity = encoder.containerMaxSize + } + + currIndex := 0 + objArray := encoder.cgoRefs.AllocWafArray(obj, wafArrayType, uint64(capacity)) + for i := 0; currIndex < capacity && i < length; i++ { + objElem := &objArray[currIndex] + if encoder.encode(value.Index(i), objElem, depth-1) != nil { + continue + } + + currIndex++ + } + + // Fix the size because we skipped map entries + obj.nbEntries = uint64(currIndex) + return nil +} diff --git a/vendor/github.com/DataDog/go-libddwaf/handle.go b/vendor/github.com/DataDog/go-libddwaf/handle.go new file mode 100644 index 000000000..a77aa0e50 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/handle.go @@ -0,0 +1,206 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package waf + +import ( + "errors" + "fmt" + "sync" + + "github.com/DataDog/go-libddwaf/internal/noopfree" + "go.uber.org/atomic" +) + +// Handle represents an instance of the WAF for a given ruleset. +type Handle struct { + // Instance of the WAF + cHandle wafHandle + + // Lock-less reference counter avoiding blocking calls to the Close() method + // while WAF contexts are still using the WAF handle. Instead, we let the + // release actually happen only when the reference counter reaches 0. + // This can happen either from a request handler calling its WAF context's + // Close() method, or either from the appsec instance calling the WAF + // handle's Close() method when creating a new WAF handle with new rules. + // Note that this means several instances of the WAF can exist at the same + // time with their own set of rules. This choice was done to be able to + // efficiently update the security rules concurrently, without having to + // block the request handlers for the time of the security rules update. + refCounter *atomic.Int32 + + // RWMutex protecting the R/W accesses to the internal rules data (stored + // in the handle). + mutex sync.RWMutex + + // rulesetInfo holds information about rules initialization + rulesetInfo RulesetInfo +} + +// NewHandle creates and returns a new instance of the WAF with the given security rules and configuration +// of the sensitive data obfuscator. The returned handle is nil in case of an error. +// Rules-related metrics, including errors, are accessible with the `RulesetInfo()` method. +func NewHandle(rules any, keyObfuscatorRegex string, valueObfuscatorRegex string) (*Handle, error) { + // The order of action is the following: + // - Open the ddwaf C library + // - Encode the security rules as a ddwaf_object + // - Create a ddwaf_config object and fill the values + // - Run ddwaf_init to create a new handle based on the given rules and config + // - Check for errors and streamline the ddwaf_ruleset_info returned + + if ok, err := Load(); !ok { + return nil, err + // The case where ok == true && err != nil is ignored on purpose, as + // this is out of the scope of NewHandle which only requires a properly + // loaded libddwaf in order to use it + } + + encoder := newMaxEncoder() + obj, err := encoder.Encode(rules) + if err != nil { + return nil, fmt.Errorf("could not encode the WAF ruleset into a WAF object: %w", err) + } + + config := newConfig(&encoder.cgoRefs, keyObfuscatorRegex, valueObfuscatorRegex) + cRulesetInfo := new(wafRulesetInfo) + + cHandle := wafLib.wafInit(obj, config, cRulesetInfo) + keepAlive(encoder.cgoRefs) + // Note that the encoded obj was copied by libddwaf, so we don't need to keep them alive + // for the lifetime of the handle (ddwaf API guarantee). + if cHandle == 0 { + return nil, errors.New("could not instantiate the WAF") + } + + defer wafLib.wafRulesetInfoFree(cRulesetInfo) + + errorsMap, err := decodeErrors(&cRulesetInfo.errors) + if err != nil { // Something is very wrong + return nil, fmt.Errorf("could not decode the WAF ruleset errors: %w", err) + } + + return &Handle{ + cHandle: cHandle, + refCounter: atomic.NewInt32(1), // We count the handle itself in the counter + rulesetInfo: RulesetInfo{ + Loaded: cRulesetInfo.loaded, + Failed: cRulesetInfo.failed, + Errors: errorsMap, + Version: gostring(cast[byte](cRulesetInfo.version)), + }, + }, nil +} + +// RulesetInfo returns the rules initialization metrics for the current WAF handle +func (handle *Handle) RulesetInfo() RulesetInfo { + return handle.rulesetInfo +} + +// Addresses returns the list of addresses the WAF rule is expecting. +func (handle *Handle) Addresses() []string { + return wafLib.wafRequiredAddresses(handle.cHandle) +} + +// Update the ruleset of a WAF instance into a new handle on its own +// the previous handle still needs to be closed manually +func (handle *Handle) Update(newRules any) (*Handle, error) { + + encoder := newMaxEncoder() + obj, err := encoder.Encode(newRules) + if err != nil { + return nil, fmt.Errorf("could not encode the WAF ruleset into a WAF object: %w", err) + } + + cRulesetInfo := new(wafRulesetInfo) + + cHandle := wafLib.wafUpdate(handle.cHandle, obj, cRulesetInfo) + keepAlive(encoder.cgoRefs) + if cHandle == 0 { + return nil, errors.New("could not update the WAF instance") + } + + defer wafLib.wafRulesetInfoFree(cRulesetInfo) + + errorsMap, err := decodeErrors(&cRulesetInfo.errors) + if err != nil { // Something is very wrong + return nil, fmt.Errorf("could not decode the WAF ruleset errors: %w", err) + } + + return &Handle{ + cHandle: cHandle, + refCounter: atomic.NewInt32(1), // We count the handle itself in the counter + rulesetInfo: RulesetInfo{ + Loaded: cRulesetInfo.loaded, + Failed: cRulesetInfo.failed, + Errors: errorsMap, + Version: gostring(cast[byte](cRulesetInfo.version)), + }, + }, nil +} + +// closeContext calls ddwaf_context_destroy and eventually ddwaf_destroy on the handle +func (handle *Handle) closeContext(context *Context) { + wafLib.wafContextDestroy(context.cContext) + if handle.addRefCounter(-1) == 0 { + wafLib.wafDestroy(handle.cHandle) + } +} + +// Close puts the handle in termination state, when all the contexts are closed the handle will be destroyed +func (handle *Handle) Close() { + if handle.addRefCounter(-1) > 0 { + // There are still Contexts that are not closed + return + } + + wafLib.wafDestroy(handle.cHandle) +} + +// addRefCounter add x to Handle.refCounter. +// It relies on a CAS spin-loop implementation in order to avoid changing the +// counter when 0 has been reached. +func (handle *Handle) addRefCounter(x int32) int32 { + for { + current := handle.refCounter.Load() + if current == 0 { + // The object was released + return 0 + } + if swapped := handle.refCounter.CompareAndSwap(current, current+x); swapped { + return current + x + } + } +} + +func newConfig(cgoRefs *cgoRefPool, keyObfuscatorRegex string, valueObfuscatorRegex string) *wafConfig { + config := new(wafConfig) + *config = wafConfig{ + limits: wafConfigLimits{ + maxContainerDepth: wafMaxContainerDepth, + maxContainerSize: wafMaxContainerSize, + maxStringLength: wafMaxStringLength, + }, + obfuscator: wafConfigObfuscator{ + keyRegex: cgoRefs.AllocCString(keyObfuscatorRegex), + valueRegex: cgoRefs.AllocCString(valueObfuscatorRegex), + }, + // Prevent libddwaf from freeing our Go-memory-allocated ddwaf_objects + freeFn: noopfree.NoopFreeFn, + } + return config +} + +func goRunError(rc wafReturnCode) error { + switch rc { + case wafErrInternal: + return ErrInternal + case wafErrInvalidObject: + return ErrInvalidObject + case wafErrInvalidArgument: + return ErrInvalidArgument + default: + return fmt.Errorf("unknown waf return code %d", int(rc)) + } +} diff --git a/vendor/github.com/DataDog/go-libddwaf/internal/noopfree/noopfree.go b/vendor/github.com/DataDog/go-libddwaf/internal/noopfree/noopfree.go new file mode 100644 index 000000000..3c6b7eac7 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/internal/noopfree/noopfree.go @@ -0,0 +1,15 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +// Package noopfree provides a noop-ed free function. A separate package is +// needed to avoid the special go-build case with CGO enabled where it compiles +// .s files with CC instead of the Go assembler that we want here. +package noopfree + +import "unsafe" + +//go:linkname _noop_free _noop_free +var _noop_free byte +var NoopFreeFn uintptr = uintptr(unsafe.Pointer(&_noop_free)) diff --git a/vendor/github.com/DataDog/go-libddwaf/internal/noopfree/noopfree.s b/vendor/github.com/DataDog/go-libddwaf/internal/noopfree/noopfree.s new file mode 100644 index 000000000..afabadb34 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/internal/noopfree/noopfree.s @@ -0,0 +1,10 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +#include "textflag.h" + +TEXT _noop_free(SB), NOSPLIT, $0-0 + RET + diff --git a/vendor/github.com/DataDog/go-libddwaf/lib/darwin-amd64/_libddwaf.dylib b/vendor/github.com/DataDog/go-libddwaf/lib/darwin-amd64/_libddwaf.dylib new file mode 100644 index 0000000000000000000000000000000000000000..0308564ae6d5fde57de14ad353ad473837e7a08c GIT binary patch literal 1375472 zcmeF43w#yTweWK!KtN=IAO>FqO*N>siS@w|#6$?pz#K#YrBwv0D83QS5iA9xIj1sC zPn+IqOCMJHxR!f+Td7rwwa5uz60~YSt0*ee=N!jJ6bup6eE+p)<~%}t&`-a6uV3<0 z&di?uSbOcY*IsMwwf25|_nRN}E+`1~C@3iC#s3=ruO=Z;`$L`z3Wo6i!u<*gX3m^i zGkvN`%KxXTxXbsRq{{zPrT%8ljLu#d^r>UVSs?%)V;w?0M=vzrR;)_3G>A110Z% z)vEm7@LhcEHS@C_?hIe;Hm|j^aqZfUv zbA8|YX@8Zs-#D*`yywA}smXhoIrHNA(Rr6&bD5vsxxQuFy!sZ5@vs)W2i0`0d*;m8 zH484k=8~D0UvufTWa?aB@lhU~IEQ&P$b08Hg1Y5b=xzi}&zw27dTRB|F=tJh;!$5f zZz;cYr+1;_;D2cmyj`0eg^#aqMF0%-N%`PU=p(=U)z?ZVFOSZ=GdHs}mzcFZv-d#37a zvCI?vWX`WuU&Qdw=TJ4 z!9|yzaLElklIKWRo#dBxRzS!r#ttml4zVmX2Nq0+H*B9XuwWrmX!;EU3uM-S?5j^WGlLXzNjbqwrd*GeU?;!a#m60YLZx5mX!1(CTY3yCsAABE z`|l9MtEW{@ouc3L#vFXd4QrQf?a}4mr*!LKr>Km0 zu#^_RiGJ$V9nBwgbXbY2IyyR5^fax-En56@H zZ8LA~0ou^9@_n0g?{A6_TmP>}@$+LPK`{4K&p{kTSOdyZY^H!6#PQo@0`v% zD4Hwb0b2Y4$z-pcBbmU-&`VDUKvVcK?NgmNF>xRO9K~9xTC&O?ot>phZH`{EcSlEi z9o6lxXZy!vrhn?$@1J`9xc&|7vVRJCfQZ8ilK+q z{Fd{(g5SCPrXu#Gb4@GO9I>xi=pLBc;VKZbp*RwLBYLV~7nYg!2-BWh6bbK&zUJ3o z4Zf{y)>FEGC-Dl&sz=sqike?@PG4SBkbaD0Fjy|g zvTvyn(iMD#8@2cfUd*I|Mo-=$u(`)5db>{m^pj*ZJ$$|(qOr;x8C$KzuTxcBUvAjv zR`6A~BP;3Sa%a%#(nr)C%6iTVf@^;C?+j#Pz1t zYKC`2OU&e4r>)8fMc>lxh3(F-?qqJiME?wX6vG}%8P*+AhqIIqO!;bUKw+8DG`37p ztdAG1JRv~vt!ANaC+Y>qRzikcn8a}PQEyV|q*3)*493RjVOel4t=Fw)-R?tj?7eh> zjITYu*bI-*;ya|ax~Af6W;GuTTQie46zg_%u^ujpwWc2-pA3D({#~)c{VgT@c*D3s zi~mYqK5_i|epAM81LHS4Gk(!B25@Rw-UyyElA3Hq33@W2h#{aP`L5T zoRKuct+D=aAa^+9*UpTS@mrWXe*e59Z~Q=qbzdzlIL&<6d;IL#DF#p44F+$epgVW) z6i`hGNv9rqK2Z%`Xa3lE{OBkHQ{s)EUbnvU`04ikdh#2c#;;ASX8UQ0I$H8xG%db` zNI0f?i=Mo5h49(BwJG7etbjU%;tj27uayX6w>aQGG9#b-g<9XV_;Rx6uW{RRc!Rgb zJ(jn|9Yay~fk^Uq+l7|u*0%G*U@bUU24-z5Z|*_46bUrjoJ+j+qF3j)^=a$r13#Db zRQ0gwmLN`Aw|}zITU4Mmub+REPUkJ8r?ZeQ@t0nKN&Z-k93EMEwfLIBol0nRqe!aU zn7%>2s1?}f=U>SBq&MB7h6=Fs2kBgKf?r z5F_%*N&AM+D}R=QPpMe`z~>feUnG({1cd0kd|Zl9a%O;%D)O@!2l9womy5h=)bqc% zUV{(SZE7-;Yug2$y0yg;!l=a`S3s^U;;k$BL$`-Ig>($Oz~5u7x?R(vH`PjZ`P1!s z2{Wa8(QohFuL-`el@Vz!tv9mrmU{H%5&v2B&wuV(9x=L-w|p8_Jpw4xzI!307)iXT z#h)OyRKc8F>WQbx?ZWMnON#^xR?_j_WV-Rz>b+HX--?7{ddkdzd{XMu9VMih$@^qI z*6p4z5QB-xSIqZzzPl6a{rRoiNm)%=b*&*J0ziC&)MDRPD&>-@7NNBMMBSS9)vF`+ z)dH?xu@*lZs0}+-W!Ten!Mv@YHtmFf>*yzEzrvOIDsb~v0CtY$D`iZp&6#ZB%}h>c!67zoq&Az zvL;lO_Tm&B@g*$~=e6^Ub9+S(L8q5>o6~rX;PF0zQ`WAl5#y%Ib9iTLpsZVyGxB~U z{AzThVP8&f{;j7@L)`jA?JQGj$S zhD`ao^S3i(^lF+}x{%NAD4>XtuW7FowyZ?!FtmyorEhZd`=|MT`Y_i2clF`xbgM~`eXBR}lu0L7x;*}!hCLt>a$7CiTP7br@jy(>2xyV~3XDmPc} zYRjybc0yNuq}S6{=yqX?Xjb3Q?GhQAvjIiBrAB(5yp*ARQ%n2?`prUA&w5{^kF05q z_A!TT=V3+caJ_C(35?AWzGNRNT08sH(Uub zd}T?DxxA9t2{!RzePeEcHJQI`sP7%h5F!E84dHsYcDpN+{Ded;u4(-B*OSRMbruu5-%`|^d z#ZQY0c4!woOq<7V0)8FEK>gL~l`657CUtGhyLuSLIHuLK-gd6K+ry_%;HV`XMxqhD zVc7Z{uwvn~oI?Wrp*+kx6z$*a)2cT(rCPiv>AWl2(yb?Q3TbgozS%{F)vqjlCC?C0 z?Aux7XhW;`?9`ZSu+V(G(CIFtPGc zkob_5A=_j09s72*lG*zi77Dg?q;3s*#;^;^WZFe^yQ&DynIU*A))VgGRtQ#(%fU+D z08;lLAB1e}3ZD(zdl)@xU{H`2qC%aTCd{E4bnRK?sPh%BmMv26>H9mi`1*EHzJS9n zG3_};X4s92K4`7~WY+u0itJ*4uwp%G zu@CBE`5k5oj5C&dEW)oHja^A7^C#=}l!;Uyye>IEXRViRcm(h^dgE&6{2#DlC0U02#s1` z{~#kjSkIc_m*yc4!Q!_Ii^q83vG<+sfgX?BnZ*J8%v0=aIy)^D$PX77)(gG}F-eIK zhth8$HleH{23v^|%iyEJli_jE1N5WR2Y7fYc8JgDugZ!LPy70+Y3=Yth!AiaRwH;t zRv3o_ag7KN2nyp$`CZMgFFqL7g-8zSTqPL<1P9T@l;CiVCpFB<>rYmG*bA_DW3^dUf#?E}Q5-P~K2i3~w$@$EA3K2fDl^T;7~oiD$7^nf_9-4_S` znH2|iig*o$Xo;P&o_m7kIH}zeG#k>-kuD44PA?Xo$tTkyKloF{dLrAlTAzdYg2tyLJ}6%#r2g)FzyG(3 zCaa5lz~0M=o_NqpIPo-3Ixx!+5B~0n2bF@QeVM&Px0=YZb$3kxNq8}h1u&~H5 z>ODfHRiWlYothIN6S>&1$5rX}bX}zAgDQ06WB&N(ty0p&1XH&^iNLLixv z1CL?fS?}j7^YaDsA(Q{8{QRE1Woz_f^Y6Gh+g~GjBkWxn9h{%P5rWzl*NU;`K#}K$ zI+rYEEz8(vl$wdzTlzxhfW9Nz)2Skl+Ld#3m3ut~+@g%`-?L|HAmQ{dlk-a+lqrm0 z;T$8GlRfWxnMSQKC91%fQfHBo9aNM`fI8a zRx4TgwwwokR`SzSm*QVPy_pBnw|GA?F4WM@kNh>&6#$W+vxrA>mhjV5SDsCm{S(rw zRQlv>`gAXSj!IvcO|SLR>s9*lY`WrS1L_0^O?AzFI;(VxFd7D8QH36EkDk1vS}Pt~ zrthH7lVt@SQMuW<8X1BNv#RZ}Ws|Kj(3iqD1v7azZvYH7%D9lx>l+*_MRWOSzO^PDEtNy}w4PL2HIX7`9nfA}^)6 zvYIuq)U+3|hL2%mw<9Zyv9UW|Sy%=bc5kM&+6wD%PE3d_mXLjAVF=drBK@WfGFsS>Zln-McD+XA=^Il5iCD^mwARvCF6F)NSK~i7- z2JY+ZvbL*n7rd;k5VTl}S2$-Zk@q`mdB--tj34X_e^u?R^%y`$^oZOBsu1o@bvDHF z_HQMp{9!R)Dm7y}{eQoItAGaxk^b3%Y~j)Eh5Qig-?qJqg5d4nuH=`otXa3CB9Zmx-0inDs#j z_HNVArD&#RX7Bcp)xHoLIyU+OqM>91Tq@-l5&qBA9a-? z3g>rH*D1l*@4#OazrI9$e$81bpJ(zpE$k@$XZfe6yz2a;TTPBzt|~?}@>CyT_Peg! zOS$>&>4Kw-h4eD^g2jLdyJ2@d*59oO_V3x;JJGObVjgW$=Fzu;zGcj#$e%gp(b!F> zH|XPeX3@=(*n|G&+eIHB84Y-~yGU>*5A%3Pe~V7Z?>D7$Vm6U}4Gj8~r=va3Uc29x z;He~I8TQPv7t-;(cKgdx>5K`$q0NL$k7y>dATVVJ zzM}WJ8?p%K>@Os%k#5~CH5=AW!}_qXW@WLy`s&%yi{!vp*u|e3Ywq_q5Ct4brTH;0BEcmL0Kn zMo;tiKTLaJiL7(SvhIeQ7ZpM`PzsED1)g;-r~T^2!ovz8)@2ox1(x!?VBw%pU{OH8 zYn*Bi4lVw3Nf$tpi=o~|XXy(ttYmDiQMYC(pIC$1_}8$N$AnPj1fwZYD_{6y3klB* zHf5W5$={-z#D=V#m6{!0@rPjllOD*{CtX@)+9TV>lq)nY8sY3-3|7Y!hoW21L`of( zSNGAH%8qoka3jyNDq|W``h;Phl3lKO%&gYx**L@JG zRy%hsVrs1QhOFn1n>tU>eo`PiDURPLs7Yz@DT?A`Qmhe!j?9a>aB!xidL60ELf#gD z((e*7x_dDnpJ1qqMt~}LpOnU~sK!5_o3!(f#foTBDqn1+bMhn7)Qpr2-UX^ZO*N`} z-s-*i+rn=%1a-y75Y&7jsJqCUzMLmd|7JXIBgLnu-v;B!5!|`-bRAjTC&0HF|7`vr zlRsy^PT)(tvJ9)$|G&=06^2meBaEz&DGGKMjdXZeE)oB2^x*dPyi4j`vMg}0LG z@r##l$iTZMfOo@ndGI!n#eJe{`b$amS^D!{v-B6d7n4oMHF*D6`tve$66uBhRIjOo z(NHu33HH-1&!kiefYo)6?-xwbSpO`V(tV`=J?~u7nKt`MWm(#+#}cDxb5IW+av1j0 zv>Y(1Xtj}?HaCYmIo2Q8%dT6aLwF4Pzn2T0#$oZorJQUF&e_bU^jt_4$O>e>Xz|;5 z^NTQ!?UI>sJfFVGv-~lRt^6>Kn6tgAe@)rE;neC%Nn%JZ<0rcqWazPQVP<^)o$)p8 ziz`H$!7(%itjb^4lV+j=6tO*`Sl(j`81huUc%zf1vaE2oW_$4qn#}><%maUo2R6Sx%-UT4WHqS{_k5o{NEZkIM2{ z{CYkxxr&)Yvln%qME!v~XA(_Z&nt^bEO!F^_#e`0u+n=3oLSy+gHX)5SkcEFigQ~p zIPcB|J;^oYD)l~@UCuU=gkk>fGN~?i5gO(}SO|ohzug(aPSgB9)+q?JcnpCp7s}Qr zrP=^Wu|qS}WnU%`L`=kw{WmILt30sei!*1AndB|nYTHP+PFrQ_Ur;GV~QZ$$!TD(GxE}uB34_6ZwVHPoF_k8B` z-?CMTKUc0|JcsWp`!e@&a4#d`oQ8JpBU?-SK$PYmi9(&}=(A)BdY|p@lY*13`}@ni z`&&Vh&%gXNCL7qiOuu$s`f>gGZ}9&F!9joEPqlheO)b#oQEKU2q14z?!@5rmKvT_9FH2;Z zVI`$B1X{CPQRhk-A-kp?e{D64EF}~5WTf7>=^^#5XcF(S#8a|M)Zz}q-)G)oiWogl zFm{RbU2U>U)C<(MDb$+Q@jhyOhUshqh51~1(Y0zFVe4v*a@s(E+shxE{gA0-gSJEz z68ns@E+GBEbySxq)zhgU&seJ+Lvsw06sXgWGu3#`nS=Q~7NB@Ha z`=Gx(sUfKBaz3QAw!dL*$gx=bfV7%8VowryB-39>NZ0b>PI66m0=em%C^a6dd1<<0 zHEOBpYz!HrpvwroqXVJ$IMUq;RgEnuV(BHfP;6kY`fyb__jAzUa7KC8;s+Y^~1szN_X6z5$WqTl?Hv zP`#85lj@~o%Z7-gU|3_zDzx&N}kuYt*K>mMb6UMT%2Vl zYnIAxv@TAc`!H>-Q4QL88v(7Ta;sLJl$A}vxsbUqmlwl|mkA$1@0M>lyOQJ`2 zNh_Tyl4xT(rA=#uY0Z*7CZU9!sjv3OS(65l*ViAuk8G5qPw&3Mmv4Og7q95k;sxT- z0jy;JvaIyg**uMp*ueQXW2rztwoB+^lLheDEP*u^O)mzdEQx#ib)05=d)(jh?QvJ+ z!*jlZ$C)arf{ow1eP~}jE{Bu0IH##EG_=2au=)ai#6-T*DV3rEt<1CEUGB}d{Yezo zW6gm-4Xp*Vg8cbb_r?g_iYzy*rwywOU z#73pxV?{9~j&8ktT5zZdlzp~%?y4#EEhP&e4C(1?IW7L6e6raweN&6y!*kvH`az(_Ot`2 z0`$Q2uXw7@WE2)A@De4c{A~0-&nQ2eQ+?F5s9yZ1l$KsJ<@923elPwjeKPY6L1G7j z1iROdy9=^2NWrJY2a>~YI(C?QUN-YKcS1I^(uem3X;ThJ(LcIF##)RYt>unh;!LGT zErtfim#~P07WVd>yAJBwBg=XQZ!Bwz=ZwV=EF37=pTGkqCENUGmBtQskB}tgyq!&s z_VHb>uD?o8_B(Vnqs*GM2iI&pIR)2jJ@EvdR^mLK@yba82taECtl z2H~iSFnAa!%P__*0W}0>8QBSJf4Noz@HszPR z5`WY4%JsT+RFHNDWg!%O|EvnbJ`c7(Z8deIWSc7)TkVvI=wrd~2t>6@3F$AA?T~6S zd1aBCg(!ToR+n@IT5(gknKKOmC4rU=I`n0G4XFlFH{iKCdZ?tx~KnymNy zG>x>i<&dp&Gnix*S0d8@p5`*THSo6my=YznznG7@wLdJTAl)R-`QsGuuf5hYSng^) zIo|V)!dnH@gC~Zdw;p~uF6pLGbCF;8o+ZQ;J@w#%GB?K9}Z>k1Bp-W-Qt+lCfBrHx?4SA8Rpeqzj3z_QnG@ zL$MdB@n93whvOMW$Gy+AZzxuTyoKSd+#0d3EtQq&tWNMzYja+_n2pf#g1{St{P2<# zc!vqqD0x=sDL1^mUdkie8FixzVpBX)I#q!`#|IzxBS?wWd`3%#nxefFC6VY&zVRB^ zmC5Il^#!RbdT-!Ap{8SWuuKFzko|6GiLrw0n>!Jqr&6hD1C`keikuG*rDhn#!81kT z!e3J8Q@+edzsRRc>ofGqX&rTMF!&c13!1JsEOxD8E$+dc@a4xNoePzef{}74Md*2p zV9a-|#}P}YYrm63{FuE(O#2)6GVRA!$;crb`o|Y60YK=F(;9^Nc`jNq{TEZS=-2Uy z9><$>VXn%Sg-*|0x|Gp&!DXAm@Gy{g+#a=r(dE3Bz*cPKVRa622&dG{23 zlNaZr9s+y#aJ3vi3hpOOCV$KXqy&obGx&+yiQ%Zl6s z6@4HU;d4Ht#hFRLNce;3#EA6@PX8$*x!7@DI18p;yLfv+^krn@W}%d=a74tUEwKY= z)ZIWJp`6FC+RQ(XVF0zcFG0jGo`pr?;9%ObO5OhO@5Rj#E7sz?O_%p-@0x6ToFmXI zOMq$*PxjaWuq_w2h%H9=g(xg`dhYoFzoNEGd!-5&S>L}bMzi!2oL93HZh=RJIBD!o`yl5S6iyOqqTbl_mV0clUPhANDH}leYBp!|De?atAvq&>yH-HxcQ$(N zh7p3vx=l~cs1?)7iN(^%1NN+EQoxK(P}A9t)YCz7$Cip@LAIZZpkp8Kq@S&~H|rbp zx*LiyDvx40hUqNRZP-Brgc@0`TZeJN3oB@{X0`L?VEG>5du+LGBeLKx2t!#WSOntb zM9ZYacZzS#q^}^IS+ZFi%ck*>2;ih_@^6eCmi{%%l&sHEsD{x}=~~=Ya>j+l>F>&e zefpnMT7h%O`Qn?e#rK1Z7y$UmAmCTlz@!M%z4YYiNA4zn@}Nbv*b4ssO?ZHP`T{BY zGSBIaQkhS+ie41R%X4T}2hmj{pxL^VN3)_SVlnfHEJ>d|BKw&TnewWWit=dIy?Adr z22&~bOhtVPZ$hjHRS|lPpkg6!FjzyR9^K*$6dxTPl`WSkq-H}UG20N~32N^L)I;CS zFnNJ5-?Tv{ZNAJbt*R0q43Yu!OS~;FaO^(V|NQlJvUArrV7#;WC$m0g&#z)l!O&-5 zHMCD5o(_8!Mvu#(cx8bQ@>lw)F#FD-PYseZyg4U$+FB=p(+v*s)6IGaG&G=~5E`nL|XV*PS0Ii*qbR&o;@~M71;* zl>doe{s)=zM%|K3044jZB@f=iev;yFjTmbrK z0eIBC%k#&QfRw*v15#qY@xxHuU+1;5llc|2BF5~Xm0}Ofm(x>a<_@hQ-gx`GM|0}C zKd2A((d1l{7uzHGGxC`_Ppxiu>4F)0-R@%T7C8`$r#{-v2Nw#7Uof~`PZka&DE|or z#r}F_gZ|*m)xS*XpytwwUx0Auwrm5==7g64l;Z)kV7>pezKN)9^JXjq5O%O1U9{h@jf zQC;5G8ydoT=ovkPF?^5Fuzr{s+GKgIkDyD>Raa9jKG+=#_%{t%miC z(U7M8^=9QGISEGPGoa-W(~b^K8KI{pBo8~)1bYqZkBfwMMnX?Utd|&%L6Oi7Bed0| zvF%3aacQMJ5_&t5Jn4)`=qWSQZiZ5fiy3M$LLV3njmJ^JATzYbq?mU1ho&5%hZq-X zLZ3$qev!=6nyc4VG4YTWBGzMO=ruj`_#}Jk=w>tYwBFEk=p_59(JjXPnI3C*zi)<~ znLrLuO_U`^NHjDIHmqjAZ!oO)>4VD8k5$BAK?BJ!Z5_u)i~Uiy7iS z*eP9jHWGS0Vm+y#UPmvV0C)^MyMVeKdOFU4j6!>i(4&*=v7_53^tfO&{eM0ZdPs+C zdH{w+uTpx$xedstd_O~tO>1EfpelWcFpHY=WQOD<4Wn`^MWAJ|=~Bm5gOSZ9n3Y>p9ieu; zlH(5UM!}JjH>ho$RHzbih`up*C9Krt~BU6kMH|O~@vXYpeQ; z>3GxI+Nx2bk=Rb`&>LPW()&D)MerW#Z`U6TW&v;S=#^}u$(aT~AmrWPCbLXm@vC#E ztVI|raLzbKRFU<<*-!>yQYSyUTB$*!<%flMDj6^f$m4N5iXq}^Y+Tvulz!^zJIRxO zbYA}g=U2)G*7NW82f7cgTcYW#_xQEaZ^IvHw~Z@_9WrBmJw#g4SdCeYRxo4VR#not zUnu&jZci$%y@3UU-~*%%yO={5aXGrvl z8z9y5JHao{8Hdz^RWe+p-Oed1C$&&F->)NmTyf*Ll2Bt+3Aog0e*hw-0smx#W@mfbi^a-%t=fvl-=Bm5A@ z9?AklXpop%l^g<7u!oxA_oJQSiA4p)KW0myPpG}%DsYmD?L;#zHNxzJ&bvGn`dvc5&DEe7`|}dD4e-8Q>|9_7L<@%fcg>BXnku$ z8~Ymn?^4E`LpVi*#Er3w+-q~QBOk3Tmx)q%7W2T4l!D}p)oa$LnvIHODvR03uU^G( zveYOGS?oQx%-et9{K4{Q2?tGbsGPLIzR%@~#^k`kw^jIY{CkR|G3D6o@DWucsMZp9 zBFUs5=ASIkg6}HbdM09h=@AFj1GNE3rcuaAS zM;O`p9*IYl;wZSPTP%uWvqE6co|)>!SB{OBUO`!@{|BV$_Tkh0`oALelV@CB1G_~E zLnrbzQz8`?6&FOW#2V-8-bA6rR$@0n7JrC2JdpVXje;)=gIcnNp1h?7=pE;bB56*CMo+C&*|?-Wnx8SLsejZyO(ek^uGxi{jZaJ z-Icy~!%mUy*>UdH_dZvB?@mU6q51FA_m0Q{@ZY5GEqObaw|1fLbw!Wqce?5Ei?Bav z`hPP$et&!hfd3|XeCv&_=uuCyOmL=6zle=R^xV=&c+>o9)9!Dee1}hs4vVn(UuIex zg?x@=SWAd{3T>?1HQvu8eU46o$A%BFQQ2@JvL^84_)c*a!N}&a-s80@+-P zi``1EYhtNucMs349r;U4CF~c`gQG-kwqsQG7j^4Ik)M(H zTm9ck)OsGpf&~@^3uLmN-PcTtsLz?sVGV!La8tCGIr6MhHl)7{_|umTE<%_?jqL_I1GXj==Mnz=IfWD}_Vg>FdE!*GR_{Oeh%ul&wt0Lu&e} zuasp>nGV7Dtg`bNh+WRJ@@#EmYimaOim^onc@=cFKfO_oqNK$~iv`2_kjM`$exiu^ z))QhBz+jxhRG1?}gO8e0ET;&CE%T4!gmEg~L;*J(E|;DO_! zOU3DlK}lj~PexWotnJR#h`hdul2bPs9_U6zI;Q`|AXC2*b}tfP*R&j=A5^>KnHaLJ zC^o{=3Sw`kCG5wrnmobV9-|ac*^4y%la_ozh*u6_Iu%PbLNVvfDVb~tniR*$x`PDl z@FQB{NGeNL@Q>{F**731J?`89f5w$V#Bv2-v@F}*dIPJk-(Q@js2Yr6|8!4{K-7_N zWo}~hNZi}<4xDCwVSY)@r9V3T32}bEkJ3TDy)*}(?$-l+jQ<3DWMT959qjE4QK?^_ z5}&;Bp*|Tb^*#0)4^ViC?6a&#MMD9rWds6z>-IPKI#B5Uk?24p{GOJ0m!WeZ)%7IB z-o)|7gjLjSD9;h`8LuwnG4WLyZ88@l;U+(3K`_U8GteCLwz%1?L|KnZ^WbMO$saj8 zSy_#`nqrOwY6GVrS@t!z;X~)e-J15-Fk(lm@Lwr4&`+EKSN^uu^~ju&NOkwT9}hm8(JR?i_B_=%!_-KNg) zfLN;;9v$nUTm5x>OK_)!XqPB_!3qmJ%I_Vqu7&dD*!-(opdf}+#-H=ak*38dCc=^W z>DxrK&R5Vf`qvbbAZzR02zG@-u~{g3(gXTn7bHXf=fL+j$118E>XtI7nR+bHIbvx{$?RI*f>*`;e^ch|&OvX(NjaX--FH}X&; z+mCV`Lhb+qonCzFWJ-migW{W`6+U0TA-zNpIX)sSaDT54FTnaeGY_ls;{e+(DDoPP_7$s^w=KnHF`e5? z5*95j{poMSw`^#b@;k>{=9zcVIS0vtLr&YA1v%AftELpUtqVn& zFY`;0cS_u1-+qiUSzROEBCo5xv^m*#^>8HDLalU6XNZKbC=UvYC@z;{xVC)kcS^kOYcm%Zn zD;@zx=0tTig;GX?Gs3{*b3va-@+>@@-^XV(+;M$Rw$0q5;DKfzHoG|G6n8AO@xRNk zHo1Mhz5ZR*)+PkVNp=~oR4=Ymh6mP+5Mhhp{KmLwITS!PDYD;3My{ zi@wW5r%0@kgz)>Z2wuY+1}BVCob?`F5sLPd6YomQFtP$Ju2)oU&Mv`{c@T#a#a5hF zI9R(a6~j*%H{z*Od zRD00G=Sd3QxOg&2<)*dSwAMRsoXRAyr?E8~Nf~U{*^5^r8Qqq0e^$eWi}D*fs|a+3 z77zwC9tUt3bZn(KR7?Qx_~{weXx&yvdc{YJofmg;$*$d^!Y%5W@bDnqqFGA};cNO( z{t-ib-N``h*A!cYS_+#%4Ym%}EpeYf*eXQp_NskNiA+JY`-!6FRhw>@k*=55=Z@#0O3sv{893E^7&_@jEzz4aktW9PHEM#koRK@4 zk&A#|HD3N$4GP98?e_8I!^%|KdT+S2RgXL%gQe9xqsB@`M8@h0e$(}Ut_FvJan3y@ zJ1WTf%d^As=Pbnu`n33u1(810v5m^eXo+u$An`l?F~jXbqwCBd##zKZMWEtUAfr-8 zLOLO-TsTk*aLDsndf$VFlS}V|vaLt23|dvRzDag&p!ESB)*$hN#p$iY9ax#lb+E@j z3?8CLtO_SOMaEUys>dX>2gJOi5Oaf%7);^oBrQ_(&(wCAz$F!T9C?W&b2M>*O zsTLP&O3=Bq#Klymm@m2gIWD(9!(LaAAM8VZFp!&N#p3XIm^!r4<#Z*K2yUOrxll;p zPa_2a_zDs6DjwEWwI~Lx)vS}Xp+3Gb_Pz8vj%)UT_Q&KgQqluyOU+1y{a7EjfAA(o zn^E}eu^Gx@sOPAVvNV-r(&#MDOqt9sORyTyNYMn}?J~>3_{$$nmfw4d0~yHFFz>ax=l3Y?D6hDLwRtBWFb*+Z|W-iaj7eLFQySb`VaHody8vmKp#Vv12 z=1e~?9JkY|BSE-;$e$Q`3+!*;0ar7h#`+9g!!E_$n5vyT-1^~$PF^U%4-nM zqh{C>o+J$Nx?Hcpmb^jE-n!C9Ckjd**61FshhLaCOc35j1rCaM(CUYwJ>?e3GXZFL z0*X(5Ay(8%VU6+M%VHu`sJKBqfm!d}oa6H@Wqo)j$h?HiT*0W~pGwT5u3mxJC%Vl& zF}qm9U$}2!9s!I_CV=rSMwNFz3hN(I=Jx`|gt}2qLG%<^HWMj~ip#x|QDHkQc}fgK zHmGWA3PlTX@h{O5cX@;v!7KcPNmf4x$dEPD7s3^@5MY19@Oj2+p){r0|AOYdD5vNk z;v&S#5IrP4oYX*mZ`3!vMXHt6nfQ|aSXdkc#Na=0S*R7fuT;gx2!PF^s4BwFPGJ0I?erL4&- zDU7Vu;ts@1N1{&oq=)xt37InRU~!R%0sq|6+~5>t{}lk_Xd3GY=Y+4R&Dn(5BRGz_ znL~5IEwT*G8WOytt;)a^{fUAp(^B+jZfvZK(ykrVmJE`XI8T<%4`n&PtUg`f68pwz z>H%1A8ylFK9%R+OTdURyiG#F8b0h{+Q*pojVO5S z=5YMC+IxsI%6C`DU|`l}AX<={qr=3@nQ&tf^PN+_3UBxBkZl^HG*OOZ5CT`6?M*4V z8l1=<&SKt;>it%k$EJ)>@objs+*4eAL;VFde>c+JBJ=XxeL2{NP$m`~k*YoQQ}vt*tUEhjtS1Z5m{I-iX6yCNZ)-|+>eKx#9?hlJGO;>q!Jt%eQ*7sG{LJU?zBe4DpYwNP3`JLMB+zqaERRC_yPT1XGshD()+{Y* zslZ59rjliR3sZ+~QTr%&mTOUh&#{v}yq9tAgRCJPZ{wH?-EuuMAqKd9= zt63U~4R*hRCZ%RjHkC6FP_3Ltfef~_l8`%b=U9rF9}0G!-7JO+HYPCgCzrNTxddI9 z_VRW?2_rK13wO@vUJ|YXF^4(u;THF-w9NX5y`Umu-^kGr*^X$5uS0C)=f*W}zo=B_P!IV&t z$Z`#5i1l@+`0;ud%D#;mb}+^qMPSFsnwHo^Gd$nFKg`Eue-O+@+~56x{95W|FxBN} zyF?K1t|A*4RP}ODRrFae_HA^z;#8dLvr-#S1s9!zol7cV*tmh${;nL2ql`R#p?xvb zq+IkZ(epifPLQhZDBJsfkptEJB4XG1elaycET`pJdsJ%l=-@7q!({^lwh8k3uzsM2 zpgnE?nzTrgpLDUvUg7R{!T53n_)iUYhhCcy?h-Ooqr#0M0!?g?F$`)AK#HB5 zJ`Qk%7DO)cX+ewc5wyvQ3q44HaHfFwNleDp{^_Ywl#w2k{t@|+uY&tPJU=RL%=fwv zq(apyN-c!In$3c&hyfG)B8E*(tI#ou817DgK*geWdDnroME{ZQFAI3)zH@bNSxNeR zUs(&XotS=&l=^^J_JZMwd>HA?zu!=$2Dq$kd_ zkT~$O7v5SO(ntQV7KB6xjM|SumaBbkYAT^|x5Q64nuIx$P{u=*0Ely;^PXrpUI5y% zqhPRy^07YnIGqapk1;;7qE64zXq}&s=KNN1IlPGxltld+`-pHo&SF{Wok+9H`6F76 zFy-UPo)vgIufOF6E2WBO;vi=)p6RELN>xq1i(B-nFPvR!K`fJ7k^Un{fZ~W_ns=0l zU46uD9_uB~K7l;t_U$TEi4_`I@>;>6&j&B&S?yPH3<2zw5cR7?7twB!6R!fkxLQJ& z#=#kyefeJT#dh?eqlnX&fT6>rN{{R9%y7Nf)9FIek@po7)Z*{TnC(?oc1G0AI+z9* z6|;x}$m`B38C1{FEtOtQodUy!3I>0Ev_}nHX+Z9e8ek0L zoS6WW*s<<-p>qx($@dy})G zF}pr|2L3Z-V>kc#Lix`rL;n}?A4`bHW0s%9e>NX3w6^|B%YROSzwV2~srb+SB5?ly z!+-vEsL;SR=U#rL|0feLVkRbwH`&bP)VCmxN>sqMzKU1vi~qCjKq5KlYK@ zs=s*yQZeDrEY@25Ru*0O9|HN_o4U@wvZ?zq23uk;Vkna6*gb+M?^$UTEERrh{vf;# zaz2bt?__zF12_7JwW*Xl<;0F_?0Sz-tekv9(|;!)*F4Kg{$B1U?_9V*eiBP8YI4T-QJ#n$|H%8F4g#r&n!ZD$oF8f24`NqLMEoC`bLp}xIGlwc89zCmSytQ1kt zV~G21jBV3aO=Q_>7BpJxWc#R4+$GHLx)?5fh#?pS{M1FIv19R>_3m7#+~~<`+N!Dh z52!wEkQV!uI^`(b9D5`E7Eq|1ukfJsmvs?qgEJa>z-bh2(k!aq)uMZgxz)!JTY3Ph z%qYH4_gg-S;3R;ayH9``G#|a9a$|iKzW>a?=boLF$I-#(-J-<2wAzMCTnkj*z_g^V z}WT!Q7<|6)6m+(hngsq)7wlvLdyZR;d{C(yxilNHCQbP*DZ<&EQMezIZiYcWm|jD%5e^TKtzZButnY z(1LG56z3J97)Pxu@O)*}o-B4|Hns5BAg_GUtek<3wU62u_QS zHAr8lklvIo@sZx%T1cf27^R z|EB(*8UIrz%c5%cEME|u36Xmq-j5Zow>jVOewjpaE?zBfvOg~KhYf5wKQGpoy$SX+ zQz3C7uPPCz=)L1n)VjSVSQBI)Pm~1M0v7z}4J;+FNaA^h`0_AIV>2sui=)w?WSMAM zE)p|)Rf`yFD`O^Pip>NH2QHbZ9orfa4<;%+0}6iy^N-D#k4Gz=G+MT03VtC@yVPI zsLs%oFg-Y_X~*%3`IC5`<{>pA>{qKgdsf-*eSw#FujTizCNy4j+dP{PQ8 z0A?gFC|h0KHnt4qVxwegarPWQFV^JoYtiRkCK)WDct!6q?c;LJOMjRz>OL5;ua-Iw zNO@v(;K3X{Bmz#jI z;##r`Jl|yf$(+w9J2^f)`*vR9b<_qtc_?HOc;sbqN@?Dg^qFM$*1KT+sh&E8nIYaa zbvH`1Ndr)ed%luK0v~-2`t>3RelC5=iy$}-8TLvg4>A7x%lN+}d$-(wc$6A&-~XL2 z;{X2Q2Z28L1;-aKRd4{1uAG7IiRX@10}xE8B92igVkRjGn-fN{ESyy$_UUn@{5ycK zGA5mO)WXJSMBEo7#7miHIe&E@Z$^+X2&(UBG1BmK24m8%{>b@Zyo18u5O@C7)t32|` zaUje;Z^rANcjR79|L&!lpntLhUDp1 z(0yzyuep=5ENS2SU-U8k2S~sFa<_*#b~$^)JIKym z(+N`<{3!VYXW~;D#U-X?*w`#*}VBLV4lRAf1kwP)qN6~c$Gu=;y&k}nw#%`CH#T~<;GdU z@WwD#<{)gxV1*s-@mX}#vkhT{w?#S5J@0(ihTc^C67bK0_0Mtc;T2~SB~1PC6k@;GzEq#gt47T zYAFaT%_6Xz&kQrtgz`%EW@#oQiv2n8RY)EmUk@sLm3wFRj&NS5t(^63t2E8}wnVMc zQdhc}q->Y=n*Sd2-3dG%c5x8vh>Zk9wcfL3*JsVVh)t z4X(9^l`y44out#_kYBnxA?nx3;d}73UKN9|M!9ex< z_PoFn@g89~glkN&4{N3oE%8+pW%2H$%v$LO-U3QJ7)$(R-bN}B0?K{n6R(2cQb4tT z>I5-TZ!Rnr$C-b~+GLiM;v!a-w|Poh^uS>Ew2x@O>1{wkJ!VMV5|3HrLlrGGO+`!n zqpN7CIP5J)1^HAD8Q82-O26fpU^Yy>aX44G>WvLK)mU{d49v8qL|!}xM^m`Bgs^;j ztvZL_--LfrEUQmuEvvDVZ&h{I$`}w^pEm&Pw)PXRQrROGZ(i}HaW9meTeTGc`^Bx~ zg0kGL)iK`IY6OybG}ebhTwV6)-IJwV&#y#TbfaAGpiJ;BuJS8+4=)?FyNZQKwpSU$ z&^`E<$nI*6yt*DUkIW@!KbcFroJ&Jl{Y2#PebX;*qcpo?pO^jicQCA+!TnO$Z?7u= zMW4}rdoIxmds}UP2p7m$ZO;^p=U8n^dH-~)?d6@VwrPPXu-YCcY^GDZ!WUw{CD@OJ zf*`Q_nUS#e;)p#Vu;1RFjX)uQ5&LcPJ|AiPaRH2;{kB2ux9^DkwmHXsODG=pL5W?2 zYx06QPI1j16Rc4z#-|~Ta6ACuRujiEpLx~Tkru7OuyzMu-%y-lyfQy}9x!rfWodL` z*7VpM<#d_-F+DagU3N#$ko6hXe4tovi@4!sf1PT-uWGU%!Gt(ocrRZ2zokW-yQM{UnVjIV-dXftx#Faf4>65geQCxtG9z8` zQEzM?o_sF)TVOxYvzeToANB?%+Z2<8S* zFaq_75=Vu8p&bx%dFuw1a;kV|o4b&QJ+j5wLw{7bl z=-&@3AwCPT!L?|mjnrN z+@GBp51(j1BWs$);mq+J!@PBCQm}5RZP5)BP@Y*V1aelj}H=JREkz7Djx(HRfocnk8 zW}(I8vA&#S#$%gv7fIr5ZCGQGNrFH!bxKc_61><+UcK-D$l3Q@R`!al`?5;)e3$nU z!46g;7`1a}RB13MiR^W6fF4uH8;@<9mvm@I*F^p_&kjBi4AxF!A}TZ7mm@N!?F+xtoIpJ^S* zi7oH=duzBoqt54uU|K@%977CC%P}n(dcZDdTCYlAz!_>dV-leqZ&qc+RauLt6{&pO zG~g~bPkd9;V2zO4$9OEf8~X#E3b7=nsEm$~+5hhstIzEJrzg;Q&V2ZzAC&88H$N&} z5T{Si8z6o!?*Rbnyfd+L`u(}~eIZXmxu8Pn(@xo`@Fn4ca{JWJn>t#e1B8A&^y>xs zJ9D9jo&*1dezD(X;lGuZGVUX}BX%Jl(gsuC?;ZTjyUi@Ewo&rKvD|7lBinkYJ9)lS zHp2OEm&`!o+Fo^@dZ~AT`xQP{xAh7|;o*ecJJ0i7j-Pl)bcL4SMdk^ctI9%gqW3bw zk23Jgb9bp~-*(E{ShL`_+nn1}ik$KheN3IFk?&~=RM*0Vx;AwftQGvMZvld)ehP^ugD#cu}`8;<8#zNH035a ztSYR|*RzmX=3*&ni*6?l3uBJEMe6c2Hf7S06{KSaqaxQgVJ8#PLt<`oM*UMpp0z|i zBERI>$Hm^YP;6A=4EwvaOm#7N9VBL|;TitbwY_T-*i!bcg%RsPDe0^w1^rH$&t_us znj|GVkb{>uFTn4<&Clq&pX>a*rTxn@ zKPPVW=I7b(?9=@8?$4@wqkQl9lJL*5G&Llk_qg8yH|mz*m@6~vd^DWcl{ zO?=6PS)jg%_>%u<%>eu7^t(uIB05OW7>a@yU!n_pd-rWMLp%F-6KYb?R8_^U`5AeZ z(Q%$(^s|JR{ErAPnFdSDS+-WRpZ_uOZBN2q_mu(F%hK|tjxUj|O-^@o8hdCg-vkNu#t{VU)<`zC+xRP}vs`!l`Y${Wo8)%xKhEuQ?j=~Ym^kNV+fKHn=U zm4ANwW4FLlawgONYWz=p+?W4f*(dxf|F4g_R?rvVU@3>`=nwq6UbEI}xGuryu?kywF=UlaY+GZh$ZO+>mqVnpO`OW@GO(bXkWQ$bQ#r{cY zHj{I&0F>E3IgpNJ_fORRi1L5Y?Hi|yz%wLkkFbY2FZ*S2Kxjqz)zP>`CiXS%M!ur> zSBM?qT-fmlQT&OQ=KxFavG4kRA@wPJzXJc35zb}2qIj2tVtq22JV2BOFX?e)$fD?9 zS*O=3v;Z2S-U{KJGC`WyjvyQ0sf*-XwLH3Gr@-aOv2 z^y%&IvDo|jd%5&FbF#Ps9krLw6uY81K2s|J9#69hUwp0jKylkV>AlOnN*nUE= zqyH8A)KuzL^jZSFmO6joRjkJOPvT`Yjt9ejP)=Pjn!YPP z^5?0W^Qh0Tf4MNoJHg8<=eUqpezJMTd3h%Xc_(>!tGvAOlg)dGm$y8~dybb^4ve8* z`N`&e>ji<~!2*@HBRbgYA7`66Px3|j?yUz8wo-=D@*{s<4_2zuzuck{=&fqPez2K$ z^2(3=d3odHjo1&aB!M}p#eYPT98|Pg-oqbgiPL#!dZyLkDlCdq$?w^3IfIeS9()#M zTS_Y1uFF9XUnhh6kBq&yEGPe}uJZTD&%g8eZ2k9imH!Dc%>2uc5g@gp<}aNDvY4|#i+${eWX zDwmEjSMR2f+fZ-F_0+o*{JWgtq^T_b;coSANw{Bf!|9r~7_| z|5^7dv^|*}mG1i$GFKIFAHx5i_bW6n%=%vj^3uNP(>q&ak^B7YKeASSN&KT8`K53F zc^njdHv5lnpTXOjc+;mn0YPqM^iFDA0j`x%wHF>xMb(Xjg6YYH=r12R_t6Fy2bORn zVX0w>#E9o>uEZ$0L-uZ;8A{$-*n20+${!-JhC{I?xH|Le&=jcZc_v}*muJ(j)H63 zbKjUKV2ecleou>wMj)OF#RTW70HO#;szIB{h~9!-(k}2&EPBqT+R&~7BZhq#Zm=A* z@~ZQ7B|u-zP(CMG(k(O`oo6Oz=N)%aRp4D#b}wa_UkWBUol~x{R1jGcOOXh3A@fd0 z;RG%Q;|B|5c+jfyZYR4RF@v*Iu?@TzTkiS5Wkh!+Kc7Tvf{vFm`sjT0Q8@u6tB)#y zUG&i$@%+|DML!g}IFcF!fImLayTA$a;@wU*fG2mjWSAE9W<`WwiIhU)^|V%#5<)*K zsY{&lPWXGSxvx`vBr`;3pF#WuIdey%1k_1y%M?{MNjx`^Fa(3)?*19BBHN_G>{@~_ zyUh#L`P7^7vlb*TUdj2?hiBZoGpX4N$*$r+(gRmBti;#tR`GS`sQ9|gUB%axu|bi; z;yzVc7M#p-#MU7lk|W4l#8o~&ny2Moiso4poW{g;WRB7B<_N+AL*mdbSCUN#t|Z%? zdnFkma5-0!aqB?lO0svosGdposAlv%&N(2)VFf6`vv;{%2FZa*D@=QCNp;tv1!Rm)2HOTQ%T=36D$^AHf$WRa2{S zhOvsT5JbuM|F3<{oHHRPSnqf5cR%y{W%fDy?8n-#wbxpE?X}|UENEB5r`LhRM|<-} z6~4139=R>m%|8@opcVjB`u+Mc`}#3~*x9zQ)oWn&4?0k|>G%Y`CZEDjuymtVorkXgk7Y&v_SK%hXrs_A_71n$HgAchRL<`af+MR$h#rU!5(Vl!nXG+++BgEwu6z7-m6ZL-aOIUn;V`Xso1$E zd%6;Wz4fOi9@or>=dm%J9#VcOk+Bh&`g!%wXRzRba=*;>_zEEgD0*w?t2Z5@6C}|_;$?b+T=;d?CJT(lHYS9=$s3E zJQy*_IryRK-p5qkYj&J-@$IXfbD6WfDirDS7?HRAf4$$|2*J-c-S5|l&}hH+`(MNO zy!m3~+ps zfJ4Py+wI`pBNI{!p-wfg4@4!N*fUcz#nh~FR01PIX-6fVMER)-$8`g}Dmq1mPYjxJ zmUXPoGe|!;j;raT1k6iZTf);`D6n-5-NN&=;i-9D*?I0nZw3do@|N_bka;Ru?iZkq z4D;2A2+R@A&W|KKjapUSN~gRAPR8C>cqii?@+R6V zQ1%@~k#SFx1(b_;S8d?N5nM$1kewcQd;99E4buC5TI+oqJFQv3fzVHUlOGOK`W@!!7u^tzjcW*t`RD8q~%u)v_UZ z4;pIc-*DL|29D5R6=2GX>2%@4oa_HSSSd~}$FySznOxg)6iT_S{Yk9vgrYrWywAO1M<#ywVS)kJhsxl%33jA z&ZL5`vgB60V>(1;<2>IU|2_PFeLuav#RpjqIcw$Ms2HW&6QeQtzRhMjZpF4FUq_7F ziOvQ1b%@<-T|+bLT8^}?zcXjBeXC@!ACznNHrC*T4Zobc5*eIz0*7R7?Q9=sTb}J- zE{v&)E62T4mpkK?wr2pj=MTmh{eY3_&^GK>mJGZe$_k0Q2D-RQS&|~6P4%$hL4EX3 zMn7fUAaW~~+N;a*v(q+FAVB&FZ5?#Fdfy8dFv%_%4dAeFrykB&3HN-c)O3V1^dX>c zb_Eh)8c@uw)ah9BDAOgZhKv8*^PqR6q;Ks!XvY&7%+vqV`uLCkT9{R< z@ey?P{+$OcdY{UK?vYSzZb>lqyLPNJ^4<+BFxLO(CwgHpw+?Ny3`QuCYn+&NFx)uO zu`LWzmHDuuk$U*$NDU&b-a5-oT&EJ(W+v7i?aL!0SSz9c`a)l-JC3BXVU7pcacc0U zb%0w!m6Q;rahS|PP~(@6v&JX+&3YQ*0tI1g8q*TU==eQy!LeuoYQes`+j->lQ!Tm|V|zAkb-*-GpddxYPt zGRYO)j;Me!Dqr(O`IWmE`YCtVkxDT(U>w*MW%}&M{I)2o%hsY*7=$)|GoF6NCuurf zX!WN}dJiwZkuWkKK!Z<2%P*8f3 z?Xo5!r42*43X$w0Ya}BHOAU@>fO;2fwuVT$@pwfneVHKbG^Xt>NAr`h*6E(fHfWJKs%vO`DBU&p$&0Ev z8s`fujBb`Eb`7;?)5RZ*)^q<${)O{QHU2!QUj`t2Z>pzMtloh8RaXoXsGGCHOH**G zzE<@Ljzd+i43GlG;}y*!Bye&~=ZVJBoREoHDlhh@1LaXV{M5-=3<}*wdv`=QrL?mUmyjb6T zPyNU}`M1D@-|=t%7XL=8AYJfp*UGGnd_Dgr`TrgMjRkbUzkPu52em{1z7773wd^PV zHWrw|rM@!ww@&uQH)37y-TwFk_?oH0I}G-3=Q9@b{ECN2-=yu2!ysajRr#MC9imG5 zrf8d%BT4F|&c+%4tMv~+J9c4@{E-KFa6nTx|KseDXPAWF?HLl>X&WsxMcO1hQF7*x z%*K%H$xmW@*8Q2|BmMyzsGe+I4w=e3;l3Vq0~l~4mEA{%jQ&jvtXq*Q73Xm*$Q@A- z-fHC`PLixhK`EJ5<^N0dN4g%r&;In^J${{(I@}ee^d}$|0jB}GjnED%(0tuB-#8d^ zgf}CtPfp>`4l9pCSG}%y>ROM!#l#8B2GL$Hwm`UyV}r3{kN7Kz%}?A4YDs#=tv{g) zKpu8PwwJS>>h=O{32&k3v0l8KqFn4HF5~KrP@0 zlJCrQ5BJJS6=OKlAC6WZR`bK5-VcYU53BG24w1ZN_fuul5>#*0eV?STc0a(&8CT*$ z8)Q1lKN0lut6_kV{h?`_H2@~WGt_m%sfe<3+N{Fe;0%I#>>EqF{FiHCdn;KRco_|P2> z*D{syYNt-=_+$61+Uro&t@x*3qWeKT#O;vJ{NL8;-HCTXzn#u`-`}tv`7`i8^~Ll> z?~Cq;@k#Z<0-qM$3V{%X%hfmdvcliT(9n!!co2Dv!TwtOS0(&)v?YV+`NtqyiHe5e zNu)~nIj}rI^X^q6lkY+D2j+Y)&gvh5PGkp7EZzWYEY=p4mBmJ{iN$7=Kg2e%h^_}E z_uO{Q2)I4hYMz5IaVVT#-9u_GeO?csF(f@7g++1*i*IZOk1(+rGvE#qgPO0h*#{P= z7|-C=wVLw;#z$uIJ+=TM&o_g{=T^hHWHr{oP0Ui!0-=X%YUgF@1A$%o_*)c1LZChw zQpmScXS&l@@iC_3LJV{GkdK)$1XXZ{grw?h!~% z5Fun1gjJ!~Z0H1a>{b5Q8ty^IlxO(sBS+cYUEzu!x46}Trg!9zbN-X^$Mw1~1-g>+ zaZWL%0AZ0tJ_&i_skV;VZqZSjEIMkhLPu>6abp#b*M5l`xdJx) zi-*>cr2#tgi#A1i2L`Q64j>>>Kkql$@_qWoObPD=^tH_K_dk@@vYQTf>ky zZnw?bDyz>TZ=}OH&H^pk5BSNR38h5;$_iIw@(YOiWD2T;;VsE+h;ci`kvG1KSS4@l zqArm)x^=BUS{Yp!kakD6?svAlk@}V1Dql`sj||RIC^ueqYbX8>RYBPJ53U8+qz2I! z%1X_3Q(*Gd(p_KBm{qIC{Izfm{tsU2V*0U4<~SDp{Cp&r2JDBjmxhSQQT37-uP5ZG z0X9f((W-wbf9&S33K~UvwSRfGZVI-+E~T4-x%AR``PvdcWsm?B_nWHFJV=uTK|(Z& z$-OjSTn8Of|5APdLkoa;O66Zpd5AfwuH2Z6%cb$~;epu2u-EHHqoK(MbfQOJjTGpE zT2dn@wmh5opZ8<`cE9kaBCkvh!ExB!Bk4)9hj<&L6jc{bgQ)|DzDTEjx^ZNq!tks- z4WiN~or$uD8yBtPPU5+wwz>fC)+~I+p@e!FEA>Vx;?Rn6KmG#{zb%gP0wHQ{0)vc=){B4 z(i#6y^yu)5dLY8=|4N<)Fn3se0YZ|7&R35oc+aC4fY;=&Ixyj1H0#niSs+KM;~mxQ z1Fydl#MD!q>JBm0YcKzoN;%IxBUZ6CIv=6{BZgDbbf8IuEHY zyY|{^n*2{@rN$z{r#D1qGyn7}a00Zl$={fjIu-G~kuWm*>e&hZ6SJ?qes+^To|QTZ z@dqLP(z$alWw}4eN*#;|jCs@Y^3F4AfL+<`zh(_e z&~pId2+bcTi%0!CtRbHIA4si4tOLzGsRt-zp8&BJ_Rn*Gw{F4zefYo34*AS~-pzKN zy9%HCn(tlZ@y7iG`FY>Nu@_&DF~LR$xe@&Bl_(!Jx^)~nwXLE+y%t-C;uUhupQY1w zYpcjpAM>rx*(d2+{jcNAxliKUzb%1$3B+8U7QG#F7dHWL8x)7Hp!4GxX|R5Z3a5lq zt?BL#XQ?+_IYa&q43w_Zs#hTU*w~PFkq}-Rj{GyjV0Mc9{$hcmaZGI3pEqMM2D3lV zS3UQv`hyv3eaG7YV;nH8re|*m7?=1Ox8+u^$p*jJE&M}$$Ll~B?xet(N`Y?t1Z+~4 z998xSfCWI>IM8Kdk>0T;@&=sO&YyQ&@<9O53FIUlqsqOB-Sf4ZV|Y0y*6+80Sie_2 z^urvK|KrZ(n{#x;>YA^t2-TKoeFFF|FVf99a}YlV@#7Ic4e|Id$8*_y&9{^Y7_alS zJ_a9kvz{sly73nY7B$xKEmwX^TOu{=1*kiKuPE^%M!`H2@8wcTH2GIxk^jM7Xr01G&4Q2O0JYHub-ltzap0py;-kL;OGj1!9mNUE zd&gsohFhrNpLG*#G#dfqZ@-7wh^N#hc!-Yhn1FFpo>hq0)JVj(`QzDjLU7ZD=Tygx|nxgS8c}HCrMtGtH$)gEhYi>+U#A%(L*n8_x`# ze~QkX=dMEN(tPFjuJU-}`Xj$PyFL89&2Om*V=vLWyJNlxvvrcgY#oa!4o0hv3|GQm zZ!=rC9#J*F0G|}YbrKWx5p@f39R+UdXJFm-M(dKz>IZzeuWVMW)pm25+M5Fw$qzrg zu~~8OTHL$c<|+Q&2b%ZM>KmI2avA-PTYsh$CtGNkuJ{Q;?jM?Yk zB4hTwP;6XB2+pcNDT0!02Bj4llgtqogZBX%L#2u9!Joy0Jz%xVf^zzLpiaD#N85p` z8=d+qU5Zw-nhDJ!XfJ6sf5kIgJ_L;@xzV5zBU`H*LI!Hp_hDg&V%L*vjRf2R=??&1 zB2H4Y=o}Ogs9pdk%9qOhBM8-7lNTb=%}{H9&}u4}*pvAbzL!qTkGuhwnb@LUw@&^A zSDXM4GzFZXDZrrvKy+-iuEG2zE5f;vJcaxrpu5_wjP#~dQQB^^7CXhE4BSAWXFxQI zrz&diE2tlEpngW=m?WroNTTpt$=i{N<)z`TW;Vj#sqiyBg-0%x7Hx1^G!+2vtwq02 z4n~K2>RgvPrjmmQAmq-CJ8n^ZH))G1K!D=>@YNR2o6CX0t<>&GUrW+|(7b*%x?p zKbg&1>w|@4HnHHuE%|@-N;?L+OSldd2XD@mwuUQhL~54XoxnFC4EGW4VheNO*$WNs z;ma@{>Ac}ngx~8~m|TW|a>ug8lP2ej9<= z!VkEC4;Cqr=F5%#l00DqO7=J-t=%&*)W?$yz*DVBF4cYQr2hH z-%d#UE$khzh}bYIs4#Hw7rkvF9Cy*kA)dYq5oZ6tevSad?MKL#+z!wbhxjMF3Y}I9 z;^*f!@pFflPV0hC?1D}spZMQKmqD_j=(4d#*>u@dw$|+b>dxNSsXDAL{)2RxxXE$I zFpUT1k$jL=gOa4Ih4%U>(lI`4asF9X;}vw;k6FYo@k|=*jh_ok&HW*WD4D0=5syy| zXUQ_O*^$xY5vSPS_Ry#5$9yh-*lC8f-KHuEqayH!A`W;PapVvGO#V>(0`~OOE&L(w zz+%M!5}Q9frIg!i!a4!r{{TMG(SLLJIi3cAm)li+Q$bE7U!>Z=K=A!D0e5Z5Pl%yT zHAnN%dNdo-0g+E+2qH4&8NIQ|d*m4{NWanMCte{xu}S0^Dq0ou3i$^_gMVlN|FBW< z53dOS(2~hNY;5wsCj3JS_=k;(e|TB(51WO5Xu%TNXfL5x6#viy{$Zml&wzYq5=6N> ztlu5s$TR-BLuTp_1pM$rjJj9}YV)^bNBW9D<4De?W4U;zEt477YHh6LL~Y0p^R{WT zwFa-8AGrOx!}OneFw*Y3hremc+vwMP!ILq7BWN1fiCcqd%&HQ$|ddkaZ$IOE-k zf6s|5upPaH!#oo-uZF4CFSl#ek6|g|>CkxtDq@uG_CIkCDzfD768*|&E8Z(>lDz|7`QcUYB&ITP%MpUDK<@Tr<$ z9|1ypf`J*u1OqebPOy%j$pmY$<{+7Hp`2h1)}?q&Pq13Nu>W5~Vk+XFfpMOI|Gsv} zXZ};=%X#i91o8Ei-@D4=jr%_Gr{|ZP_O)>K7++u;?AOLt15E#BoFG@X=Y;#hF{Bnf z1AGnbp!t%$oF|ZBP{o(GiG}&WSU+$FP4xH(pJf~I=p`t!s?I8oXs~ku5l&-A!O~a57nj{~R%~2L)y{+Fjn@Z%9E{~05P+-|OTKyN76DjyR67=EWHQl^ufDdmM`FxP0 z>E?|C^6_?~Ps)z<#FB0V3Av^q2xp)xLFhC~Gb;x_tzQm3&HmlE0q!V#CZv_Mqd&q! z%WpZfY7KgIr=Hz7H@E8Z9@ihopAg#|D*ZfM3A-iTb6WU{&iz+vn4NTpp3MRxg}T}6 z%}+RMdgy0_HfvFGV4(3hryS*iwSm=+fLm=%vrM%$$r&Jc|0jo{x0|Bab33xiG0kjY zyS7B+(6L@uW#Ex$KGO9}L=QutwyEg%@Q9r%IuK!2l2S?QJk-&YkyH?sBn7UrlirM^ zDpj5;P}b&=@kKVZXn~|TQKdOZrBS<^l!^_m zkNS3?`j+129^sS&nab7?DK=mlD_XQ^yWpac2>4<8EeVezT~G&O3M_y zoO!LpUJvv%Omsw!tQvV@Fm@%3@!TE{YW}Su<1?C4JT!S9a`}hGfdy5RRzo%`I2b-p z`<;gM1k|v5sH;zaMRDYas$IpA-mvnVt(WeO{0sR~m*594;qzh@Eh7$^H%1@)Ipm+s zL!X9W0qxNZ)s0way@?~|Lpi5!cy1upGe>*$qSEZj*g3#qI&m1zQ=8h$feziHTF0LA@LJ`o z6xLf4xE!de-x~_+Z41V5WySp48=QiH>@Pxq3sU}qK=pbczSp(t`%wxUz;!EsLLt7t zR~r9pOm(YbzMuOMsP5N2j4hz<0oT9cv>=s>9?iMXEsc z7x{C~9g4B8LCFOENM<b3!e^r_a-ztPFMIY z0etsb2EN;<@LgYSx(eSVY3t{d@>?cl3Bvm*jqr{q!qeH-Q0WKZkr-Ql7BSv>V!ZcL zSWlAnI6Zqid%eF$7X_9^7GIA!n}V<5xMp07M}^_c#U2a?Ttx(D;F|ZxB zSvgtMmi&qx5$hG+KV(PJ&-xLnQ&`2pi(MhRpCPGA)djMftG;9q?}B3gFQdIi%|UxF zqy+8h2#BO+N53BJU03a*y?1K5KzlDBGL80jp~>+aGgQCrkR2p@WLthBoag3 zuoLruD4F65pB?g<|2zP2p1TTf_?qusk} zD7OmIeQ}h{ljJ|+1t(HV15eoQN$5rn2UfJsOKK28+V`|2qmX}0Eax*u=&=!H*0@ES zD(laQ62A(1P0$Vu_oL~`*=S!l?=Whv`l^Z}KU$g=4 zN}yvVrxNpipjYn#v3>>Nsor&{R?YL^Sk4jUOZ_-4iDVP>C@V@nj~`p#X;M5e_?1B8 zm)-QI9QP_P%=JMa7Qznr4{b>vOB)P3PH@1YJ=6q(0_P&n2eq?5N?QZVg$19GR`IEv zt4C3^G((!kyu2yrDD1B5VTf*4b8;k>*wFacSm7){lNHK-AKlq7 zHa4PF_0Twg#vYniAidK)6uXw46A7dyxyVTRhw$MvuF4DDoj1wAfyZbVYh2T6gE$bX ze^q0Qi&}9cN8moRf!mGLGR9^I;+&q1JMZcA zdCJ`OfN_1h<~!ShQqO1${D`IX8Dr^*v)kD=JvP^ZQ}{q>TjV9o5qs{0FhLg7r+U=F zscoS2&G4~$Y>L%ZW@U#zfQCW4)wmEx%&@nYnI7XuFSI+X`|#O57y|1WfYCE;@$0Be z=6@^)r<-drGi$Deo|!t$yn`7GTZVm|yr}DVMY*SQ_ZqCUoP4=C(XVLvaA z(001A;JWFThp(LrZKso)%1+BFf0Wuzzd|OR*ZyL6@L<4tcLBlk*V&@%T3eJ|_AZc= z=#xN{-3C$iweJYlvi^wxsOC7pl_Wa$fM#(CaX+tm7FGJs99fU)B(QP=4-E8*1?QOM3G@vseL+6nP4h%$< z!IhyOn|u!O*d$u4Q<2UiLq8s`HNdcc#&=G|33zAU-tkk+*uzo>q@W{_(5n|TWQ8k4 z)YNtZKEUh(?kCS`PMyrUWU{HNigP$$UP2OoO4h5PUcPK7U-iT9Yf2087^Wg!Bi zz!*l~)c0L|8MS`;cUnJ-nE#)sKOQt9&DLDJ63Fd8Aw4w;d)aOH|0Di?WQTm_|C&zk zPP`Mo@-^R`bbAXIA-{{lTzblpr_N97LmdXZo>qoh4TP9hhI$w;opvy2%hETt7CqJ8 z>xi=(-^t;z#uAJS_OU?rIw09N{+olw^psPVgG8?8x%|(-SyH&>|bx= zLIzAht_Yu{8&D-QCN+dgU)GkqCrxNVQ}xEJIo5KFF%C*X#&)++Fj=?)7^DHGl2xe# zaEu0*;p`r8l)5o&pl(bY2n!znT6jEV*T(bMRG=`h&H5*b;x2~V-m>s9He?{13aSDV zY?gFrDEf4`7$+b>;|1#gf#EGT6ZRhLi52+)W2fqx>yH!kgLi(iyK6BmzI(g7OlAOf zrK)mp^X1hyK2NkhA9F~d^{3_w-cm=Czs8GhIB0zywlx>6|M(`sr5vdq ziQx<7F{`O;gnc~Oj0i7I@59o8(`^mbT1SKR>bHPZfYfoJS;>Tc@ur}ez6gjP&PBdt z5JR*lQip!CgV0O93ZY+j9g66IBCOuIm`)w&B!#wDU*9#_cFB2S?FGoWFIf98AOJ<& z^528CmB8OV`UGAD)T%=-eM36*^}nkQ%|fGrx5;bCWn@VGd&$}70Ls_~rhX_`y9#|K zSbG~@>#QH+m83mf%IvV}@IoZ}b{I%^W0T<#MgZ9 zDvviVfjZn3)djv46Vy<9;vvIB($nZ0oWjS3-+v=lz&+${&|6gf>J>pNW5a*V59q(c zrAx$yZN0LQP$!c-ZBPLMn*m~&0DjVdEGOrsx(8y{*+vrTtk!w#G|6A9@>gZ%M_up# zRF+|t^=Bl$B~LfUgYKCG^B&`2REi|gcwc6opm|~zW(u)W$QV*szLfqWOyGSp1dE83 zg>cA&n|%QTMNFe zLZ$Ua%7ydbBOTG0hUsb)4 zrK#JjlTan7vbJv7VJ%?ZSXgZR5h>)zT$Qsn6%)4-E^0#<%_EX`9 zCr?=I!}wVbNis3ZHVp5eu+Mx=aL0q25uluPNPx!h@t1gHZ@e*QFYw2PcbnfU%jzS& zl{>n;FI72zn7t2@EDn_N||2+EiMhXYt&lmLdhX%goWTicm!DRFoNSfGC##E4wDmYf3j-+qT84FRE5A4ys0zkHb)dcL zF-3s+jMq?3+`6O}sn7*0pwEiiKxwO4xG6Zn7+Ka1E1kcKb9%drZ| zo5rs`1gR~bsutXnu@*$$Xq1IZOEVH>zS*oIpsF|;LHWu)$e=2kjwk3aTV<$){nIcT zR(z-9Cs~Qz6h&E6@RGv1U2BcS6Vu#z4a0=>vwnNoZ{@!DcyYD18>pdKp@wFz4s2vF zMz>egaM)V38*;omzzDvh-LbY{ZPl*q2+We>I98@H+#uu>;zw?*+t=1HhvS?Jzv8-N zf8+3+!hvUtIy#^uMqN5})nR=4ESU4-RgS)swhn38wku|Fe(c8lcu0C?9Xk4*yPWx< z+{NWSaHl;#K4qG;6#|Ul2Vw67*@(h8L4X-JL2v~Q8~Iz-3`ENWc|@v6WR&nHlz`#J zbze0@VoV$xz8ujg|8fLs;KImj&ybo%cZQVMu*wYSrr>mD$OjxZXlmIrige^# z1SNSlp4YnMhoWyue|$nfegOZ|5RoPFtvevn)J=9~o(_Bahv|c1n0{wBZZOa5jUN=6D&ClrxkP?zFOgkOswFZH zrC0^{k%=U}%We0FM5EpDK`oarXR7(+zmj3XIz#g=7iCX>GEd(yhj%FtK)**8Qg!Az z7+}~yFhZ?BtC*i@_cXwUt;B|B$u!uvN&hSWP>Oc&@zZ(M=bopw+QV#U@0!8cUzycu zz61;)_?=vaVw9oJ*|;os07$L$#!Nfyz5#Kh#Y~(Me31KkQwsGiL(Sxm^j@Ll&}0g3Rv9@KP&%&A8w7u zKA}eS9&}QrXd`+@RQ8cZQ0)Ss4uQ}hr1NeeTpzyyfQrPhw~(2&ds`n5%=WI2TTxgS z>*E+i?{$4#g%Z5$V+<3=hSwn)%`8Bm*2j}*puL5ZKklxN&j1=>mGu!{ma#q_z}S1% z$J?_q*Td6Tx#md4@`BONx=t%zF-bns6-B}s`#1k>?30E+L zN9vv(9lXyQK9WdEm@aGTDV!?MWfMl}2ITNyM@N4Leg80^nVNy$CQdLuu}&f|vE1%< zYqc7ZYlwLMR<`&6Z5dZ}^{$-jefs5~5_|1#0rhS6Y^3@~uaIi!#VDHeAc(x^wPW!$7-f^ArHS{O^x6|Zt`1^iyM!p}M$YE4*#Ci^xBi^zeV~<0n zCQ$nK$Oiz)`aL2*z)=QBpIES3HL3uBxO#P94r>^p@PWghYBF+O{`8(_*n$0fGr-Um zB7x1H?z&uIm@_ZiD}Q?VRp3v5jPKxsezgH5sI#R#_)~oDmHym)YO);3rQ zS(QLG@4urCL9Ol(W%^5jy_*sW$Bk!0Mw1bGStLHRr~V}nx{~|IrAkn?ORX0hK&{4d zkGdK&#E7sYGlxmJ`9*W3(0?g!i1?`P?%+;Fz;za zw?GEL-oX&a8>q`u95yyhT@G^DKTP_|rvbzD?vzi)>kf_=l;0t{i&vWdm#qi$4#-;F zLi+1rWC9A2!4W~gyk<3d14eiFR>o@0x5u07>QOP2G}RX}Bl#g?!9J0s&t5`|^Q26f z#Z|z_cjpK$+;)q-6)ePTd&E#%!CW9E4a<>;uhQ5Fgp~w&Iv%-}@krtH@3thop+ye*#cCosfX}4g5jh z@VzE>Mk7ch$Vi6g^Udu4^YsX@Z>(mPgOk)3NuG!w@_h-XrN6ofEj=8u#Lu5&74*h4 zQQjrUCFydLXtUb4>sVVXw|*%*AzNEki}$qj18vxFrFYxjgc8srvyC{YvwHYw1mg!) z{A&=6h-UW8552i#$PH-=q&SeaK%gV?h1-}KB4~U=1(zX^^SYJCpla*`II60*mi`sH z7_X6ZT#P;SPx!$yUR{EPZQXzur@PEvCwsaH_dcr|^T9>;1S<`@Z*t&njK@X2myPiS z;F*fFK6){(x0T_4e4=a`*GQslChEnqFPo$Fsj8C4D)xe&sH#K2zeLpv3Ar+>>hXvm zF7YjHJmo-$-z@R%Zajr)h^IzYqN)JDYGqaxsrV8V=qi|^f|&>sRrB#{C$3WQwGvhk zm^Nkvvn&LzqP#!}41L*}j}|Y|JhXx*?ShiKl@y zH=M?Znf&&-s2k{1@aR5(dbA{80P%81m-bu2{O;b*TZ;3JrR*%G&$TA=>!Nif=*0|4 zWWt(@FR4C68INW|lQsv+4T1u2!I)Y5sr$PFt$tro{y|pT1t^884D5k@>G=uBz>(UQ zw8tYYvD2ZDLS*t^j(tW*Jn4W1oGtR_sc&@GVFFc$2~>o@>!5pRQ(_d9xh8|k8YP%NXu#vAISO+XMkZ~N6z@fNFVfAi z#kw)B*qmHqoL53-b4)Nct|%D8XOlbVxB@+PE(oKIG@aFw8U&p=+s@Q8bTFvwOnt z^u%IW5qJz5cS(%7Sn#;9M4@we!)L6^#mgBO;?71lZ>^KJWem(aSK!yUi@yYPLNKeh0)w>VpL4t;O=TjDdM)34V>c`0GH- zRDf6|7Ko+5e+S|+7N1zmfPa8kV$8)lKNw3SNXQ$%1LE=Og9PTSQ{-(K1M|*l_%-h0 zuLCht0b-R{AeI9E9f)VL_{3rc`~$=iV=kV<55^J+67t6HfOx+8Ac1*nmAoxu08D^i ztbRt>iR@e+vvR^bO=74@9~{{V5F`XGUM>k4^W#=yL@ z9>2z2{3XOc)E70WR067$v?w7l`v)75oMn50rua88QnCadW$f!XK|cZ|t+M zW&(fS;3lEn54xelT6HccnWs=ADN)qOz^$>js$?|U0SoD8HrdlZHTdGtD@Z{)8@U;{xu>bzGws~@&iJu^D>L&?QTZ9T`3smo_Ea$< zt)(Eb@tnu!8}W>O-;ODnI+*7{Z2$Og*nZ@b{%%ESXaNHkf_qu2`TJ(pl-b`k->|;d z$JzBYsQMVV^__%L(aJJJS~Fm*5YIk7-*Psd&3k3L;Qa;KY(TGbI|R%O_@`#&Hq?N$ zvKcb%4^`SY5+E%D{;9N2skAF30%_?D8s#p>JJK@XpGte1N?RonNc&SsyKoNVl5^Zt z*GQ^`Q7f8&-AP12tsxlQJQ<0nLG?k=))cAnTk{qq(3S>%)TJ7=9K^Em- zK&$x}GN_<=43-#d*mr~vaY}I1CBjFEefnlGVZUK42H;6|wW7R?1z3vjlKk$}3(oxm z%&*%K4Ve$h*J>V=`p(c}@M$mymtrOP>r(nGmi~gb^h)#}@=x^S|Ai-iac2G#_m;n( zC;wuVzpbK3*?=su+CnzaFAEe~@tS%%13$csCXT1o>vBFisB|pwj-wo%(EO1ayT8}9Jt!$_mbmL6!{(Exk@}kf0`)knUHxrE>#qB z^b6&?d4g`vD?UBk)BA~8_lV#e;4F4nWB*c^a8wj=TcJ_Pk}5D zT>nLdCAJU9hsxVV`LZL&LKP8*!?-?T%C{Q}%Yvo5=02Yq=$1fxZPyiKCit_!gR|tp zFX2{@sB6PTAXK?6Z3)#01A{lwRv1o~1C1RAz{&wsx!cpK+?rD5{t`n1X?C+#6GaxN zb3>K;Lrr*%F|iR}viGbP&H=J8)>Dy*@~?A@@Vi*f!oy!Ec#3Y$; zLF=4Y@Lh0))8irIn!;jgJL2*|WnmdkA>FRhYCgn7qvF|ls3rL}Ui?G<sI1VXY_@N}|Gt zqkw`e2on(sda)Kw261H;SU+KCl;G$#@2T-XC#&+%dbR87Mz;Xnt%sTe=2#Sl>(g@T zav)fFv_E0ZLV9R1v~YfYom6EP8`D!NE5Llp&zMh5kTkXsLlt$#P>}%{IOq|SA}W|x z<0OJvAkBmodr}c-E@aCc;i2jNg1<~CTzn3{_WAH(hXq{>QyMe_p_|=1#^W-WkRFlE zJRA8T!~krRzI}JbeLvmQtcj=$(%dfTv2vWp#Bz^bnlcdnp>qEzZnmRw-Df{ zhS74`QJsZ3fOu}kiRuFU+VMpyzC_}6JDzydESnGF4$6Qn^LZ0e+31AYz+QYG#O^0V zdaRlNh@?6ub>cA|jQy3>&|>Fh#GplRglRiQ2=FMGe^tSu7V1blMj(oP1!R(dB4T1d zvoDaqAiea*4DIxT;s;4xzWym-fOMUE)U?$~;rL6{lm|ffqbBxPMoo*pvL>AQ^+frd z*VX#uXXpZDK-B7hwi574+&Yz@n1AI^x^qk9T~vT52%4u_m;aDSfEBv0%15%5dH9h9 z(*{>IxRj`y#X8X~QX$Jxy7?cic(#Vv*S>0S)t=m+c%aO{h6X)l4eV?40uCEwL z+?=S7&QuaSMoiaLi)SltXUVKf5a;h;^d4RT_eq9%xu4tTht`BjwfqC`LmCM*P;Q5% zb~qHFyZ(ef3Yu5?a2YJkqRptaPH@{%1|X#!P_0DQ;c6p49HCdgYH#hi&@K}5V9Hmwr)+QS2}{SmMZ5-n5qk7&4+q(9&qRFhx;<}>``Y&W za+_+;e<1XN-HSF7@%%sSAC$^VoHxHIM;Gm*e^Aj+;L83Hs1xh3v1$-w!-$HoEV~PZ zLG5Mp6i^sUcm&lYtq(&gW#;q+l?k;NATiDVYLF&9V`DmumTLHksNUIa-dXVCb(0i} zb8cXDl#nj(*Ikwe0*J^Ahp(6(on5REq(ly{zXMP_Rz5Fj?Ps4SUMWlo(NV@7q7=ej*L{dR>0%+wIwHjzNVI#W%=ip;Nm2~!y)5xg7&HBny>_2*$ z7zF9RbpV`c=-DmYA{&!Au+O45X!akz1RApKKU~a@2O6!C04)E&>MC8H3~Edb4#DJA zVbExHJmSDZcQcK^w!zwR>flPgz$uPc?d>+k7y)7r+HhdzdIH>XXl2ZUF}c>^uHBuY9s&PXQu{T_i}ZBqgNz z_Z1VpOVKEB*8X6kGlo8$nlFS(Co*VxmxZO#(0cO1;+$0Im;VC#2Vxh_2_b8lit$^i?kX)1(i2Rnb2!FfvDasBs(UpEX|kr$v9tp?_e2XgjWx zl#u3k=${1XpBWJ-G;UDuh6(~f=8JolNV6_5w zpUo-xq=K%|VMQ={3n?oTN=*>4HH3_Jp}#^K85|E|7cXyvscnDdF$qF|oEBtsaGQyt)3iw?9dC{w5iY#T%YN}vH?MHaLx^+H!-h~w=nnb-^9;gU*P z5b^fw3bfY|xOORS$XJ*M*$<9GKDHimli1?APJKT6HPz=c?C@fQZr^9} zFRFdvYct!HpDOcaz{auGV*8G7tAO#aj{va+h}#9?0v8;+S*eyz5Px}Qy5(I%{KRGj z@!t?;!be|ivFr1!RZ;{HrN7mB5YIuQ7~Zn1`#CK1&OADA6;Cy6LEH|^Td1?QTGh-3 z_3T*gRSzh^eSrSW&Cx!bw-wWZa7yl-08dOhPrh6 z@X4fB6IR`;szaCCVXYl5Md<9$4nCpx=IZz7gp76N#`AIye-|u%L5Eh(vqtk45k31A z2=I{5Sn~i`4KAtl#W)BtU~)h%l&bx8fvcXiK+8}P1A|a{gAe)eowKkWekHIh9xvm2 z7{ZSmigAnoLcGZq3DqDYIv?8u4`BxT<4|U8QI$sOI7@CoLb;zXiLbiRWc4@*Sz*3F zeALk6^4pLDS%2*(v2klv5eBNrUnPaX=N3TVDIH#`P&NlZa$7g&69Ru6Rv=&zr5P95 z*#XDtF|j9t13jF`d~SVlI$9Yy2_1X_S_wVYTi`5oY4`G_e+LM0>r51)d|<|MFFjw~ zLnwa&drwE0*C3CZ!kY-)Zko6HWK?VQVQ+!7fcH+`dCV!1JC6hLxa~A~r4KRRGt=VVJy^;%Z*X}?1XC& zg%jKY)Y*UoE(~XbHSKscl}LC_U7amJb#BF$zxUW@g713+S`Hsv7!1Rp(Ss6$2bsv>a*SGJ<#Qrn3AjnBp`; zkC)>d{;+bK$R7zKn}r34{e>C2hY^MRG>EZ9i2aQj`YmIJFm`arxUmqP_HqiPx1bM* z5OUq@`Q6pYWq7!Zm_dGSbUZ=a;gu5rL1abnMVUbEYqKDCEg>k*!gEqI$`8^hI{s;oi|m6*B$MT#R$IogM4P zzQW9b!J(lz67np!jXDf}G=6~PwniWNF_s%5UeX&=h^h4yh8$J_84iX0dKdPi)L@_tdnLZ?{YX7GH?yqA6NaVNBlZfPXj=j*}JDN0yIQ185)D76)ejG1_@AI!kO>J1U14t&v{vz~3;5 zXVFQr@Zrv)>jSm9WD+^k_-cPvUMmo^qYAJuE02~MM;ycM;>?mEwpSgS6Pc(FTARAW zSu}7uuSM_00t=Ro!ie6%JD$QwYBfs{i#r<_)y?65aPGq*hQmxpR@*Z^^_1{`7~i=E zJEMtNhS3Duz8ULHixx|naH`Iw2EE%-el&V+4qyx9eci+4`!`!`fo|E!SFs}WMG4s< z;qI<_-4u@sP_2q^6MqP=A(FTwe1vs? zo0tp5PQ07^34m%khUF%#Cy>RR!ky`pMelPb(TzuVb(rQ7g<4s@oRK70Sg7orv8DBr z5cV!(OXKn=Hn-qf1B6SAcaHU3Qm`OS$Kxd!dxW=+p(59iI^J8qORqrf4R%N+nN~9% z6;=I|6w3@eRi6!l<@?r2g=hn#^IvF4ntoaBL8veQnMuFA5CGK=3>z2< z%j6I3V4nodx&~zD$bo*TECd0wBM@B|IU5@upl$&HGsZj;#zVG%p`YUL6T#A}vHE_+ zlVkG;eB<_W4)(i`h)+Sh>;yhN0p`s~ylm&%{gliGH7Lz26o-usn!Z$pvH3Y`7iP9i zzf1u*Y5IkBEoUm)MGU5yv3VE}qv9~*oFkhmK)XcgdfAL!Be8>wa|)ZF*C(?VDt~<{ z$`TdhF(xDB#N0j@7aFRnSvn2$%f2XI!6+`Nm{y01d1roqqFCtC`k`v&TiSxcB8Pb> z8SjU19|y7Kg^b@Ck{|~c?_y2^50SrRKu)c0U(;!+vAy>=j0;NY*I7^r} z@u5TuNd#b!g)Y|g8mvBW{#CW04$SHCM9j8bKEO+-G=^9|gtBbpd&vWGI9+SdMQ9&X z5YAAR5o=npAb~teh$v#`7wG1b3Jtw!y;p!QXxC6wDW9S5fHQZkW)`xz=tSh(%MBIe!ojm00@LBJ#a7-3JciG1BsK-$m>ughb44Os}U6EgH$EL^X1Bs@A5*7zvsz zPz}8)bOyg_H435OgE<348SPbrDC_yIv}&JtAl=xYh_VeJ%H9-eEQZ{Q8heA(*tv@N zsTbVQGs$M=1uO#1m!Ot;bOGNpzvRyWVZ&iy*^$C_a2HsBAhd_H5p4jANvP&!aa zPm3KI9h*Uc&8S_S4~VRO1F5a1(73C!$|*S&{yhH_y`9J90DzM;b+_m_lLf!!k)N)^wn1DqC)Z~IFxbt znTttPL4FVI7eNDHXPN~Ka9kb|3Ww8Ct9e+^K>62ERc=%ELSOZSDTAEXuo`euAjRKN zETeyb&{(JIM!(k-fyGG+=AtViYcQ$0LP0}{mvT9p-Zp*b$OpmL1iIxECcng*mi2VD zPcKE&D!9h0*X$whHxI&HSRZcKBUxT#d-4dRbK6v_5X6D)oUf6k;CHYXaRcEfi%R5b z-`Z3D=*h1uhv=}NG9RtxER?nQ$PN}bsml5SGKxJ9I+J(EcOW!Hlq_1e0y#a@VpF*g zi*Jtd5Q~5CJH(<0pKd=ggIN6R*tGCzi+Uun7?(#9i|^tI#Nu!Sw(tpieAdd#@I&F# z-{vS{aR^FP#NwJGx*`_ex!FrB4&a;Ff7v2MEUrhE01c(xP)1!zA4Kfdd5D9+21g0F zj820;iDK*egCLfA`?z!mlQ0na5NHwfVQM%j!}}VQ^z#=8QD~|l1wll@GSw@UoWD36 z5-&RVP%Iu_8b&D~s18M)B5uK-H; zq^xr%8}SdAhNmkX`zXth1QE3rwtW=p2}1E6hVXr2F*Vlz%VS_6C2l=|o`PwV%V30v zu3o4OJPA?U!p36fvGbrQLE{5Vl7z~&7)iwX38v2*h{Bh)qkCnotVK0qFlMKV{zCF97+X;1j#n%n}u9o&iI1}vlIeF3z?5}eD4r!bQeu0*uf&JOQ zyHo=M#%tEEa03Kqo>o6;U>P<;SQ?K_M*BLfEVNJE`RUxg`Crw(9-Z6QQoi^0Edx9l zz+L&B+jj?I_S(MlRj&0&A+gInb?`avo zSsCLu7{iq@e%s6T-o6(A588Kxr+t@;Mc+pbO}8(RF@A8&*#B;o>s_RA+BX7G_%f*g z?fadyubt!f_p8~y4r?NkX14D`t15So@dJgK;rBSzGj$Lw8y~2QlaO1Z-5*HYK^VSe zW%u9f{kRF^?eoQ-c0OP9NTaxaRj+O3`65h-&I85M2LD7nNIh0V4U91-wDaWikwJVf z@mx7bt?zWyc-tOHGS2K0*10&xAhrr1Os}^LdfjmM&|OBPe3@1Er6e$V_aFCM1>D=NXZ`5#7Mq~no&wHJ8AQjUv`_@ zGZ333EafX;DIx#Ht(``7j|Ti|uMxyku4?`>`YJ+?KaX_05n^#iI!-*jyg%2$Y><$C z@Mr7ENhVSkkc32+w!lsc+}H>S$)OU9jW#DqaUBk2L>vxI(y|3}+i1^4agv`YPV&R_ zS;uFbD&~QX4BX)#&jD!s5%rRL40OZDLb;owH}Z)%7!oCoi^^@=u%uQX81-PmX%`On7tq>R^=;a3s^BX8233TfYPip9ASbnDYXK=(keE1yxwym)~G_iV} z?x9E7;y$np=mjTxui$j=8XREE7c|v->mOt9L7tF-e{h1mxBd&0me|k!Yh@pK`fq#> z_7aXk_UOOKM}C|Am&Zo#*?$`!&FsI%yuE>wz>)BtOaphEWxZAZMNwAQ{Rb^N+dl;E zPnnaT00Q?kZ5TT8%gO?_$Q`HRxOUd^@YRs;=o_uHE5k{Y@_n;w8v06)nqo6nCC-d? zW?$bMu29D$AhHU%2j*j}+B%Gi66!`4=*EPya`5a$#ynj#`mU3m3JQu%5b5xE4)S^4 z0KTYBwP-1 zBuM+R&F^^%?o&r}w%7=|av6I(&~12%v&oO+CeL$Tdpp#kAJ~%x(+7+#R0;TXtTCir z?Sxv*Ku#6+Kv;{e;}{NVPVPeZ6~d-H2!+1b$M%m<*lOL>!Xsagu&F;N1rPj@A0$Vj zuqb_+e!Mg0sX_-Sl#_HwXOFB; zz9?e~)n;e6hZZsf#R-2MIs?kgA{{0EYr>3w7(!%j|C!qwb!h6W-^)(>mQ~zCq1WU7 zA|!Gb`x9u0PlTdBm2@gHw^(=obvJrt21s70RPSWPUR;`Kb!Kmp}E!hffTe#ngZ~ zmh%t#$U*aJ;$0kA!TI2F>Ev}CL$?r53{TC28%*h9ujvD?_yYYI9MlTEjL0V2RtD5- zVPdefJ+d`aIy*m-guwt}E$mI(tkoP0&_1-2lsewV=XU})S}7&wWAW@1aGU_}t`~r_TmYU+{odhMTIW6{(^Q?8 z+)pgS^OE~AYWWm1)2YS6vr~&tf%#5yBB~}o%2SZ%Jmsx)%4;CWbuY}#cso$tzk@w( zbD-{A7~c}Upz0=HR=5<5V-a}95^E;fjE5q}5{6ADPAIl!_vM$)*DkE{?C3pJpoLtf zM~;Mb2w-7&PzFpwzwtioC#j>^9_wJYEFExUP|t9hu?1GKaPQQdS3syX0_Fk>ycXdt zz>1>wsnvXlg3`TTPx~(7A_4NhKPxb*5qjuv>U+b>+-|5;L!$jjq=0(E0=?46PRj#r zedShRvp;x=7JT;5S03#G0CY>U0A1)SAH7GS)P3xqZGTb#zKzg5&vxVi${4Gjw%L9JbXOAxGEDyMOk0ff-qcM3QN<6(oxPM^7{e8lnzVXlT4VvSC z+;C)YF?u6t4hRz6%Ha}e1dzH)!ETjDMDUFAd!iKVK7xqgnSik&0F9r(&YHpFqSB%-H)hxtw z^-j4C+}M%2Os&t!zVOxdm4-{Hg%X4oN-_xJrHVp%TG&sGtN$b5m|$r&k z9C!RdsL%-VW=LE+i9&_OKy^nq?dE&%g(iwNCUwv4r)L;7c%%3B6J6ur>i0%og35+Y zCeMCw`{^Tnm3#a9nT!n(S`Wz*aup+V+}obpA18esy7pvq^+zMyUK1IK{t`BrwYqlp zW?WU6HyErm*&X5fc{L;H-1q+rSbaC)+)Zv0j{zxr{Sv?JBEFLQ{)2m~wfFV+Z996Y zl$mTfww_f)EBk-n|Di6+OJ8*R?!Nzb_x;cKM)&S-dCmvq$e+T~Gg)T~O6#Iq$MQ*n*_7*xQ^xcEp{x|S{m*stj z|G%@h@Ne2%I2B%i1pg!46aT00)9$mqsfq31D*m~0_ksUw@XrIF{Mgk)ckB=TQU0e- zR^7_%xP<`JGW^MlMFHm|1~?w5L;@aZ;qeGO^5AJ|+kqa9M6vIt{BgyGSAW?v%lbLK z>t^l~m!JeuK*XJXI(PH>pH9=iV6w@efcraBi~a|MW-uoD86e5BZf0|Et(xYp==Eb7 z-oF~r9Sd^~kS(8)wra&}gIUaX_N%}ii}>?9dUpTmS?g(P_&M?((yux$W570Qf)f>o zrXAq}rzYc{9ta18iofg3Z%-J%nrAr{)A0Nd%k3w8G>6Z=P?p<=7pUd-3SzzJ(v}zN zr8~6S<8*(h=w}>jLMQ6XpB&XEtK-lrIC<3YHbLI7)_f4J#m>A)UYoL@&6~R%&k(k@ zBl<*@%3RP+V`0s;vVIkGJ^`uMJ5A2(TT{C%m|d8yu}-afxUgf%IfTG)uE` zU>7w?S8;YEZnDdxQq{c*)v^=W``Joc$C`vVDm)t%dCJ3Tvm}Du6k{4>>U2n)C)yZg z1-PeD%yMzbF&ob`!iwVVAw;V3yv%IB$LWYHm10{u zB2PuUm5%VKh|TGUd==4>jwnzO&!;1bRK%oo#56{j{wnMfII|I#f8v*h z>{mGAp>A1$9_M%=|a>@(bGS2D~+CciOM`oXbP}y%*!(-=J^nTiWzZDUOvouJJ%=< zLG_i|qv!a_+ZwYY$Lq0kVC}mxI{>LytfDArp8501Seej}FH9ZlB8i|FMn0#&PBTlT z3FENu1?^E^+nVgi_o%(DZ`>9%PaG#-Yyg$^Gf!?+qvuq zxo2`Vbs}s*9}X}EJsaq;u9DVUq(gCouK}tj@#K9d)NNiZ6kBQmM9^po;pE8J3Xj4U z=e4bcqrcNQT-8l^_($_n$&>LuqjqH$29EV%@Lsf@hvEZH&vft50CR9aFpp*m{P3_1 zJirk_lq^6)$C+PQ0dY3&W6Y6M<8k_-Fo$mFC7HF%q9f{F)?NL=bENQ^7f(@hU<8i2cwBRk>7+q3MpB-6`GnYJZjU@8` zF3vA#fyiGQSdDM^>z0-9Kg)-7x79q2YB9^9x^rEAW;1?6g$27AX6`W)dz0V_k#r97`s-8UmHsjAu%wZ}AWDENDJif>$xb^K;B1oZfaiH^EWq=lb9^Jl=He zs=}IT<2FdvpP?x+QPzZ5eWTZ?7%Z%IsjV|G5WA#9AM^<(yt>9AcV{EPWM9-y{SzF2 zm+rW}2wXt0M>~&!w3^qjlJQQ86;#Aa-U-5m<0(h0c@}BanX*TEUgk0kDRc}TDswa%d{{f2n+PQ-ht zbVh#UO?ATii0b9Ht@B}m0{Z`i00+%+prYm0{o4-Asx)Wev>Q(S%&BpV`mn}+w2ER`6w!(>BT=^CB$CT?lrFYZYfD@0OP9B$Z>xeWkOW8q zDh9BM;%>z|4%L7f0x0=^pL6akS+LlDf4@)r`@DRNbC+|^@|@>9=h;uP0WI!KlU&5# z-SMcocL6Ri*Eqhit;$#S2IVXJ3cj)lM_DJeedb49zf!!F8Qv(kY}+p$CqIH(nAl|D zJO2-_$s0Z4Qr0AKHBM+%+99wk;0N}?)QZe)J+7|8&I1Z4&sjlYqvDrBXhMbJxUq0N zUZ1#)v?#|2)-#Fx=AV^V%>J>7h5WLn@5ycYzpdSMq~7R6!Q*R`?}EnT+!($^^I}-@ za=SiPMrg~1g<+lg-!5)pR`?bmET9G^X&SFMRt`>Eiz$y>fHrz7!UM1 zDlmAJ^V4@lUC&i+S4@vlytm+0Bl!0tyc3ttq&>Y(VyE9tvtE@wK(RW?{~^xmz}Bo2 z(%Bu-Ib~hszo{aD(d?$O53!XMYJQ_qam7}tS!~@s$-3n_6~M@Wl#3u|Yrgz!9DRdI9 zdX@3?slw!Do8bk*Y_=95N#X+@dl7 zK2l!wTVC957VI%9s3k=hj%rU5!!e~w7>+{VxitpQ^fV<{RG&1vA>)#)PULc|kfa<) z6PL*@6F3uL0zpEs-8)V(Q-q(Mt@0PLiz@o zGo$zj-k8A~cmd-9vr?Dbxt$j2M&C_yTVKd|Lhq!JJWMSIlTTxeTa5E3-mAnqz`AEc zoKh9Z5ZnXQXE>nlH`_%99uP0gu_vLjTsi0FYtb8$XP5aARl=^Q^FiRn*h#q#|D47;sAAkHkw41l6@My+ zsFV={Q16l$#BKnt#q2|1ctgs19N1HglD*#0d~gXjx=AP>R-&ayF-K+?EB*%Nqm0Oq z#Pq@HY;$?7dS&6YL3c$;k(N@BPE5qyP5MTV;4rfJcmFQZ`$1{OV-)imfbowS2Q*pP z^@Xy^8H|}hhiQ<0E3ze!fu){Q9J+6+89HYIJ%!W@E4`&%FJZ@2FYD!kUV6iq<6Ks! zx+#z7W}FW;yOV4IsUXpZ2Ba#CNf4;8QYO%mVyi5(zR(c?NZuNksKP0V6q&ij*6sPl z*7VE0R^f;Z0y}g|zdq1Q!BVZTOVk3@OAxMeSA?~Omjg@HZInoiL8#y2QW+6qifJ86 zz|8D^i1rGJ$D&71WvKS%0Ugdkzm8{&X3|s&Oviy=x}2#ybbH8GWtsDkL@m>AT4e|h z5@0wL1}C-sWWFb}s=zb~Fx4l|rUND+hp^u*ZNaobCQ6e(sNXyiDBd(MUzomjGG!L7 z8KTk(^?r1$jBuZf@YUogs1cvgBrQlIQ=qqyN3zv;CNTx`5>tRstB_%GA(fV>N_R`8 zyFkC{(AUgl=pB^V!YxIhm!qMVYfZ|pFLXpJb3_7JMJEHS)%=CRxf+xvUN-T8nv=X% z8R)0Td4X@W@jxAWU~%{!tykFTY_VFeaL@>@EDTV+1sQJbO!{( zuF=z&X)Zr1$^k9(8e?~nzc&L+ctiw1qhgPYmeeE6rBQi+o5=Yx#bAIpG{UpIRo3bT z`JdMqdqjO|RP>cwlEjP)1I79ofH-%p&C57cCFBU0@ zh`w=p;U8|h-r_CGl>l70*`;(7?gcg_W0kpb z35If+9eWzq<*Z84Iv9N`*Xy4Kekit=ALrw@<&rk)D{Zcdsiv;-fIKt98_Q)};iseu zdjuO_MYVsP8G2kAfuWNg$h_x~=V80?&>y4+;UW|usuy*lY<)`l9Qz`;h2rXCZ{8<( z+Pduh`$UaW&$dbSBRN^{10J~R($FY`98K~FzBZ+j%6$ljCUald1yA z2}v64kQR4D@%vp~QZalHJkgA7Pk8Y_mtCd`Z_}+wWukrw@UW<^co0=}HUC;l7U z8-)fZm<;4-a2dUhs&5hXEpypA2KG^N`BpLQB!%!fQzSaVQ@nXiFh#JKAA4MksfqMm!Ht4#DS>QF zf&NG8vtpPfT||x%?1NtAVX!K4IVVrTXbY!C4A*gcA{~u(vu(Z=y=J9C3D*_}6;x9j z1(hP3frr?s9Vk5`jU_|rJpDjH=}~B>BCTUmeA*8;$|_+{D~#ezCv(1Rwt+c$Z5V2i{ZR5k%fN^m5m>@r+_F zCylf5OlcphCiqUb;F0u&M0NG+$p_|)UMtbbwZ6lb!WB9j3#4K(HHKG^d`lfw@tbye4u?u_a8$=F~K0;$D3Vx z@|=(!QJOZ}-+^SwBT@HA8tgWVn>%D6(xgiQ<1oqB=%88f99*;x03jkcr^y$(K)AVV z3HZuMqHZCFx_K<(hw4(7L>{0!0*xjI8l@BvX!x)3`~__0pLBrq=mXwc<@D_{5M26p zw$w%A(mz61bg$6G*3g^4o-gf&Es&OVrn@n19U;t;U_OQ%TQr!>q}e#XG{YV04>gQl zeTew8Zik2~ZWMruuG#(>{1-Qej7+%XHdRHs63gH=HkJ1Nv&=#s(tTxz$UOnA8ZWf!7k`C9m~AT9bg~r;mI}Tp73A8-_z2YiZDyLT zEfTYr4WW~qx;c^2V5t4tmlTjJm$O$LhYORe=-=Y+2mC$3(<}K@)<+xve}Y?780-SL z1WevYtb{*8d~Y;K>#iK)`9BWvBp_8GCGcN_I+!7HAmSj_*R%|wgdRF1Uq(5PUNfe0 zTuJ#d4r@raFXpAtbA+8%`>{QW5Zd447sYYD-G{ea%WSRpG1Z+BI8B=^Rb&56-uK|R3BtASWiIu2Q4g?Zf5Yk7FYyt-cjShdssle(4C^} zA@VnbG#>tB9ol$K9F4AjFeXfuuF4Olq6H$5LH`|EGF0xph5fLM< z>Eis2e6!%ty;qvytTVVUR!9aIZ$CkA+qdaP{O4)mB}pXl(R&k_qy*hz zq&xMCe1Ni`4S^76unM}DqVe(iYqdYxPiYOBDo7=QCJr(~Mj-r#`u*feesDtjlj@H0 zM+BgzhiBG>O-AeQ`(|?L4O*3UsNLBp7r7p^cVB~F8-D}H5DazCxNVTI(1Nr`>NL#K@ zrUpt!2idpsBWzd^1Zk_+nvtUzutm9%zX@3?Qg1t_TZa_!DF?Q3`s2VG#wEp`%Km)v z@Fw&0KZN&<|6+K5y7Mc*`$u48J9z(z?@u1yQ>B7I_CY>6F}(Mvwmf(>dOV0pxNt;rdT|yLFRhT&<<|!iCvpk_?YKJ(*%xm$6 zr^E3d02y$Ii=OX+g9)4tIo2pz^Mb5T4)^IsMQoq9#dpu17#TQY{%vfT!shR{Z)Yg5 z`7UQfY(28^(JR+hpLJVKa%U__>MFYay3`@=!*Ak0VxNhM(G!B~geGU3d3&{X^)nPI z*&R3>eJPQ!MLnQsDAy(U%U(-Jst0~Bxj|&m zP8#%tmYe`wgFL|{Ftr><@4)Lj&pYrc0aHo<*sM6fdb9`FmB1E&HS&qD3MCp~^jiQn zD<|RwNDlwpcDzb{h|Ry+2|JnpEH(fAWd5O3|MdJnccS_4*M2y+GY*-5XE>eAf4nov z^Y1y#*&c`O*E*a3Xs6TBVg9u|<;*|m-P!z~s^&jS=AY(d{%=<;ww?b2oi_MY=6}Zt z=Rd1Gz^(+gGXH$?)#e|D4>!15vi(cg+nPk-H@$pO3&i(A{~+Ot;zW>{l&n^z40pkkHXfLEi37(gYwlFPk5~Us-)@?Gg#ErUec&59p#Ef zmPpNM&&B`}=$i&H~8z|8OPBoLjz*J;K>!ZEk`dUl7hglxB~uOnC&bSN|H z#DMO|2A;fxI<4*`CqeOnE~cy96_!V>16M8R;I z1(3*Z5X*m-E$Poh>E#U#4X520zAmK;TO$<5#}3`#&BNN=Xnb2#*uwrobxN|)0uMY- zq(PCO+}3NuwtGXpi-+`q%%zv`lfW+a11yYZ_rXxUuLxfN+yIbn=dp^GvWm*GD|QEZ zSDh=Kir#`<^IwYISJ(BXc15aAD?b_tysn;NCJ4{x!+F_tUGh79;zjGhft+I2#Hg5P zsOmI|yMyl;(hJnl$!{Wyg%l~VJ85~Jr!XoxF-p>2bHoh0#ktaSHE^JJbg1Sv&chzo zpqMlKP#W!=t?;yDpA>TuU{hQNj8E>c?Vh~ny{>lwEFt)fB$Sfk9RF>-Y;WQl*6|Je z=#58n9P}6ymaE2N`EuAoWr8AiDW1PAJtJ@-H)dvRS~lBbEQK5%_6#_T3m}It$m&Cy z5A`Q23{}b*2Q{)01&?GK53SQ{6CG?(_PB6bfLmp;IOTCS^=W z-C=OFr@|>Gy6p)`hU&@L-aO!oJY4;OZ2d9<(kBMD<|Z^!TO57LY-3r;I=`^YXbhN_ zh&l$XB|3-+p@NYqfxen&4s$9MhA)PQtUX@%KlTs3jiE*$Bf^*l_E)thG95eZpUB=XvEy^SD52&edJ!4-3}09nk{vrS`Z zwHcm><*5cA&C3T#B&s)jaY1FZ*C>vJ%U?j{Rf_Pn?L1)de>wV=g1WL(7G*V9X2jSd-8o!^VAXB+!T zY`K5?A>$^JTi&pJm|#nd@xvNdP0f+iaM}xEwXt?$8QgFaea@?KTO6m9ehIl5yktZ2 z7#m+O$qC`v^S&7xoyk*UbJjvhZd~(GPO#C1qWQ^axEGbWo-`9JL-+#v6 z7iP`JIk?C-x~+pA*AZ+!t{3GquS-tq&5>hzmw!y_@t228&gM}pYpfOXZ-$sPtAcGTsd6t;cV~10Zr<|i}oXa>Zs-PVD%Lk zpNg%$3{vq8L+`cb83Y2fygI4CUU^p`IC^o36udA@jH=xs8e2+=pLsySAcJgXn&u zjx!UxTx7GXqBlJ=w#}|j>v~B(pa6xsL`Kt-l5n8a9Xy`3u(-qmK}TJIK8uefS$0X| zxbWrq*51Q=%^8jMPoxq~_Zm}|cEu&du46{kV*tQ2W2>&s75Nx6afeINgDvR`=eU&x zq$E#O>6!78t})PP-{4d;yS{7wB_-q&tlCaBhxZj195Wt@a_J7Xc3GUm3h1K!#oV}N zmXGS1Z&YSW16F;oC3V?{^glJSL>?S|tEAwIC397Mbz_Bs@n(j+k%~$s7^2wqo;d>* zqj)9eXcIW^Q-oM43$m=Bxc;qtR3F;Yqz-!r2wI#xbnzUaA2 zCbLz*JyeQYZ`KvLE&;}M#o4Y|C}#2Btm{In_vO}g9U|qUri zJk_m?PQahe%v?N_Q{>D!)%`1@lfmynVKcv~&)n*n?mP^H>Ej3WNf~22lQwU*H5R#~ zE;X9VM?DswPTz2hxtQ0ybezH}jfk9noYzovii_*y$GTNQn55|7Kl8hdTNKcPOQNOTGjopgCUc zt~$G02`2&V+3yRVeMK?ab{rTVTn$!~aB}oRqV0AEYgti8@oy6%Rx)h+_!-5I2+ePO z+iksS?OXrC^UpsI<=P7wJ3pLuRyeIZB8GTtFR#rxd-W_u2hH6wGxF1<=X-qL%;b{` z=4=soL_}Mx>-+lY&&UajQs0m{TLe7OJ9twQO*iN4+xCscJ$P~9oGk*W=;T-{!8gw; z;`ya>wg}9k1+nLIcib|U=U2?xBG8Kth&{JP?w`W*f;n3RnhAon%AHpOYgzeMwo$-A zy8vw1KJn4t#-j+H+@y;0;_(~3K>JtD*pZfx`>Wf^EUHQ)P%~?@cffvpizUD!uW2EK zx*1G=T5xNREe<)ZSKOgY+*G%5+IeGivk=p~GlIuXH69iUBr6+z_<3lvCG|BF)(Zn1 z4Dl-Rs=Vh^n_^dHF|~(AFI2@w)th@hkdmH)=OoO^2nsJHxuwvSN!rezaqFAGljpp7 z`%KqyFI~zz%9?j^@=G&(xZ(>gBD1YQ_U1L;~ai1Nx+_%<55fnymfE zk9cUcEN^Xn`?GXog;4Ql9ZV#7*@r`l=hO-+T1SfWYP@qA1m8S0kzwxOJIAR!xmlW& z26vmT-NrLD$#1;jH0e-Yjq%KO)3tqhtKg*Zz>igT(!YyC-k6nX8C61nEB)XH8xs`@B`73zJHx_9aOV1vterol|@J(i~?N}843tNIWwJf~XY zyInA+QSjY5lD7+ww;hj;G#>ab8Fw|vbc)oJRl2gc)Kzs_m7<+`6Ik9VYsz?FIMkpR zYC|g&f3H8q)4J*2LU;G5`%HZ=@K(k8{Y5?QQq`5Ab)i-!2`;+9rS7_{OzTlK7Jj&i z(WEgz1sELns?&APgRMP`pyXza4B&rh`A%zAleJ@$GdqXihK9^JE|ZgY#5-q)Gc%VO z&m6D$xXYYYg$y6}o!dGy?|8BCOr7z}kv7i{&&)e$JOlprB131t-gI~D%B*o?S9-^} zimNhcRb}agD@V;Y!}Gdv-8Fd> z8G01UTZLE|!I#0?$UFQmiQdHdBkWTe`4;*#J{v29Q$1On{ySyqzwg{+oPI|h;(Sqk z_n`;RCwoo3vBHu^8@||iYenCM&;Ldu-4BzP^20ODIkkcr9_y$luh!bLUZCrp^PZxs zF=G6j0`d-cQtQj+iOsp_y z8qO3?a(l>}Myb&^=cqJOZ0*Y1#i;A1H{4Km z>K}&Ada@us5tj)=SEJ`kpp;i1Jlfq@Az^UkwfWAsHaoha4X^V!K^rDX14*=@P~9if z298GScM(s`@B~-nu!z0uQws0T{Nx*4fgKM#N`1xF+j{NxPLc1^T=6B|be004vkFS%x&#bdMYnxg|#0 zM86~sD?5a;b(glYPS>zzO&vK??wx%i4(-wJ%Hv*!>S8y#80)<}o6u!tFP=f!q~$cA z1ge;>qqLkJSthf0bcV4)2*2#(y?>}$aIY+OCz0M%`lRUJr9w8uHAIl4#_ny7eq=$d zX$0?xKk8+Uo;)tx#|YjYf7H_){YIZi7b7To8vS7pbM%oek3fg!$|HyV2k+%3@_>G# z$&?uNBU${)0F;mk3iW$J3Y|Sh$ZFNO>}f_6S~& z;5LKX?!2DL>#5xL;JznytE#`=t7>xZF)Op?nc;hks>yxa!50NV;XVcXGgq=9qh5{s zEUb$E6I8)*<#gGX#J9L_VWvTf5Zt3dRx+Td{fhiPmAKUZoF^!6#XX19rHR-&Y(KV6 zzm|yvN-h(6ly1D5nGzh~S~hd@Fy7inf6qtQs;GMlXOQiG zwio&G3v;-9PG8E&Wb4!=c|G!}ZulPVaEx5Vk9$Ktl_&+|QS-2B z=?BSG%6Xa4SF+y*kGA?bI#(;8KR3hoyX?DlS9EIoHvY%A@kaR{YhS9gf#R}-9}NCm zZj$-uh%^`Z75`&=H!wb8nDn7WkLYJ-?Nwto98 zBz$~~t~sM9*OxMiS?V%2ipRNQ6e;{9u!$p*^-rEYmQn9qId3nZQ_;xefwHE)=7UZIm!O~`I!#=xsMtX{i(!Fkw)JCt-fC4lc{d2#f$}jS9&_6I_~;!aPb-uj z2_6sEm-$?tsV{}_wmzi_2%`T@T~hb(LA(d~&fY-iW>#WA-rX4-bqD$W7$v0N8)uUfuibbNz4G>HFSn@xmI7w^n~@L zOwW9EDbw>`TmiGie-xO>PN=6x5G%Trwrgliw{2A1!G6P|2Y0FVjfdrwgUzF*4|nN4 z_;1n^^*!Cv5L#NKFQxtI`cm32QJ2#Gg(^kBYaygDaV{2R_$xcJ#lJXkc6Y z>Lj%#6;$Szy553{lCpyOga+9n_3&l>JG zo^PE_#rNceQY<{&lvm+?@BbmTC(FtNAneJ}`{~9-PQUze^Vy54Ps_fw`ASOJZ~sz_ z-G7Uoi~_21cA|6jrOZI8x(+TWb7$Qr=sA>zUt}U^_)Z#jZ@7Z$G(JRi^Y)>m zdOq%;4MB@Gu>x)Q0rAg}9V$0IF?I=+ptTz&;P@};WC&9v$AW+zRSmz4fFEmjZBjVflVW5<>imG?U zR*}gk_HUka5awO(G~jw`XypT~LqNrW;Vb%5VE7kx2@L1odexIl<2)Ipu6HdF)D7-YwA+n8{=W|(%X!FBgH;L_sD;p?oDl?-T#WUdw0&Q zIn1B5+n;v*y4`iZmv)7T)9u0xY5I3W&)x5yh|gUT{Zsxl!rvaqR}S=&txpW^)(%_T zF_^bJZGBh!OZ)l4VV&$lhwN{%WjphgALkPj>ouwVS3K6IazX|557G5sS`(v#C?2u)6hJX?&{<}S#4ZQgmEcQ@oPOv4-?+&(P`mxSs1PXnj zg(?{2N>5ON63$b+?I)mcv4+xGCPEnzgIjWaBX7%|{~=fzO%q>N`%bFV9DON4=Y6|* z;1vOPN_@l#=0ev;r@Big>Bh7z!>W^*kNEy0tlO#0r8(LD-ezzaN39TeQJO8KwfrRS zdoilCK+=mO`9$8ICV?1iP<>=o;IuL^!?aN4N)^dHQu2(H&sO!F;*=&M7xpcJJlcPu z<}cQM7uCK~rd|8eKi8MMH+Y{D=q@M8;1{8riN&8t{pYLkv+qu1pWW`yV!0M9WW&sQ znhg{CPH9a79%{aw^N({CE^+>9H??+!@K^3fwsHqcbCF=l=iv+AInX6ZJ$fZ2_2{bd zN^lk`{&)rBRAwx&f*1_s(30x^JEzty#e3p#bZBINY%h?#g68?Sa^6As-jEYydCa+BzxumLH{zY;mBaXuaw~z&E zzTXFWoK5`u`p6h~VQ2ng*#>{Cs=?2spvixsoRx)yUgPaf%D&j)m-NFq{8Em?;z*@C zji-w;$*2M16lF(K#lMKGLBEUKhT6xo%a(&qzU{-&L)slG?P6(M7b%mrJNeM47|M4} z*eoe9bXWfB9ne5q{uefj&~7jODWuxM8GIX&u$de)E$-qE|3t0wT#M)oybPd-gr86s zyBSc(p0kI1 zKG*f^>%Qu`-YJ0~e78%ESd2zc*U*)CZ$Eondh1))zQ@9c#d`c_CE;qU>ZP#?KL;M3 zxJz3l@#gB}?#xc^&y(@~L>I=EXEJyzf5w14;Zj1&ZeY--62ia_pvPmBCE*-8iz8I! z&iJ9T|8U)@LuXM`kZ`6n+a&=>ZC%U=K6W>kq`24!fRA19V^QAlP^6!WxnU=>fBmSe zqI!GHnB%RoHQ7H*2TpY9oY16P+KGhq&XX9ngzi5{912$CGS*Xp+4HwA&oMQy&xX`eJhOK@vSAB_Biy{_zMi*y>t%O1P*MuPgTe zJOUj0=V9R&e6omy&rVi=!Y8`QSye%yj&vfK-r-O5 z&DLmMoS&vX|4dPVP}ixkx;``qaQaY#{{zWKID$>AS_KW(+C%`;=r#lo7_^&y1bx}^>BDE3? zz842a;cp#!nq>rj79(E=A|KJPDk-9-V&`kg)n)%=wXD;(Wq%a5>Mn>vWD6xE4IeOq z3E;d#jqAFjPw-N9Zt3XtU#X)Wn)lx^Yk z*C-oF((!+_@+c3N))=qBDm4eZqBjz3>9~{QL-HZ4LT&O!(&*V7+eq+(#^3p4j>v{p zz{hP2Ny%%Xc|JltIJv&T+a1R)k;}Li3V0~_@Qg!n4CIX;A4=PqOh5{S&k_R-T7{~AJ|Z~$a+zZ1{B`3T~*-tN1FLog~D9AbOO;S$D~q;i73 zQA1&8HC)u81`$nEXPp`{#@DCGo&(7_1LnXlVHLWjQ#?3sdSiXLc-X#ZuGA(Ri_;(f z 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 #Ji+KeO9x%brBX7Gynrq76h`gRUG<7hkDp6fs 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

^XmZz#hMPAneC05xsxcXL!um99$ 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 z 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�SVqbqG6(C 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%0DKzma{jtoCj_|uMR-pvf)&~ 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

wsW@#v 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%0D#CarpG=ioc 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 z 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 z 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 z�bH;r3aT&w`uhvj(3BFEvgMH{&d9@S?$&Gh*8t)2hL3xciSPpSEx_ zj?>^>=^DqSYhAiGxYyvl;gQDo;bxxw8a#j(8fP%vj1xBaNVqku$}NKD^6_v}&oSKe zu}N?K|^#2^)MQ{D1u){=fbYH_ylL z|J6U-++!2Cndh_yPaAwzgJ%ssufg*MU)bP9gD+|DvcXq2xOI|a{r=DVcaJ8YRt;`9 zc-sbd8oXJ4L+~I^9Eno;6;NkY4EbaS2nmcsGcrW;Nu%SZtzJBo;3Kh22UG&R)c2^KCi*^24C3VMT0MC@Up>IHn??i zL;W|n-QaB-+-dNx4emC0_XhVGymy294c@Q8g9abm;9-N0Z1AYT$2WM~;FB6WY4B+c zo;LWb2G1INUW4ZizOccI24B+PWrMG5aO;$Y`fqT%!P_>t)8Jhj+->mg4em8~?*{i9 zykCO{4L-QR!v-JO;8BB*Z}7OmCpCBiFZFkp6h7^Q7XR-S{Qv&{0}kK2Pxbes9Dbkv zo>;*99$!6Q!Z-Ox<<_b7dOK-B^|>}Ye5G;+e#-jQI4=B{Db@2H{3y8(AE&>!2Ji{y z@38Pk^!K$0K2QH0MGXH|IVbRYm2(RJNPp+e==ytB4j-w%Hx=-`^>@Y+{<+4tPOInd znZHZIFVgr9{Dn`eoL%^9au2>he>e2ur|Q2W3g92;`4GNXe`k;2d+YC;G5liv9W#OV z()*_Hv3lPOex~M`!@t$vF$?%i{k^Y*f4$E-zi%(g8tnY>f6VvI6ZGF{*zhM+Zw`E^ za&X~4X+9o&H~pR6hkto$HJ<=}=*nt+L-^;a!wCMM`aldHs{g(sfv?c~Q}_t|9X5mi ztiSK)@KXQXLIIy`@`vB8zuQ_v>iLh*`r7ben!f`dDR<%DXn%R|@v1`~?knd2{+!l5 zgg^dGwJs6-JAG~pKThK(@VUw-g*W#rN7Z2r|5cvA-&39`e9cbPe$3!w^xv7} z@Wt0w^-#cX);vr2-s%I^>Gk|S(R^(9DayxzFIInc;hy@i2Vdjr>b-pU=tIt&r$&;JtTV8bty zJMeGRhh2E4{@}sC)AK%jvi|#-0REHm4B_wSeIxh>+Sf5W*8CIrm8$0y{-Wle!9CS& z4nIcgTfo0mJ(qCnvTDCrXV&vys(QBJOHBWP-=^GLc#GGo@jdvuomBtuUV5(p{Z;YZUXPG+*0@&`&RSJ;P;ME{lj0^dKK`}Hh4(TdB`@@IJcl`S4%O{Rcis`GoLkTK5S4xaJeX7i(W6@VAv)3O`2k%;4|q z`5d0B5_f6r~wO9Samuekz_=Bp40{)ctV+o(5eQkyH{C_p)FTBNR z)qEWI=E}{5|Exam!JpTBeE1;Kf8Zhze)S0fPby|l<*ZgXRYD&{LfYW*zi>+ zsQ%$Y)t_B>Yjgg>C#xU&@Y^;20RE%-{Q*8y>k`2;)kzE=rn*YtXX_kH;Zw9O8T<}; z4j-oZ6!6N zX9V9w>mI{LDdz;fMqkxGe9bj0&)^Sgo;iG^*0+GKRL&**hC{0Htr7M7?@=Av@K&0q z1AkZj#D%}Ee(1q3Q=jqS9n>cS_|~1Od4}*`wJ#!gq?}{;FFMB)_*$9 zUTEDT_+z?<#PFAO?kDi8bPlHQPFnX2K2GbK!ynVWDB$mF{v~{ja<=|i&%d4egAKn@ z&pYszsuLGJOy`0J|4sYRhkvSh2Jo?}lMueu)z!L0@OuxbJce(j^E81!t=v-hC#sVS z9&7*R@GDLKhi{|$Ea7wXxz@S${I^pdu;HzBe{kTb`jrdcM9+Kh4b{hd_|vM}0RE+N z2;tYN9wPXEROd1LTirtv_)qc_-cfa!!MiHY9KOo@{steZIxOKWhFAT>8d=YOSB-DO zt?Sf(;1}uKap7a-9{eh~4{xdQ1NcJa8Nxd&p9tPw>mI{Ptz!b;QGF(budjZa!5`B8 z%Hcn1`~v=p>b!*CpnYVGs^@>5^0DdalMeh>eXa{%SN8`GzPYJ?_)P7i0RDygdT`Xdj6Z}y=?d#^=AkEv&M1ZlhvO+czccS!}nGW0o*hB!?#w> z5xkY^Cx+i<>L1=leJ_PysJ@-SZ_|6_@I6$|1-y;!CnfxDjboi(&wp#Jmkpn*dT`(q zbRTo!uj+XZ-d%O*!&_^g2Jp=^{}BGB#*g5;sh`L2y>zZ6@UH47DSSh%V+LQO&&}Z< z>6|Ly_bcZTzP;{m)&=$a_tiSu@Xa+J2fmH!*@dq;qq+xr@Xs|*A3ja>8Nj=0{1Dzj z=ST$KMC%yCztQI=@OJ8ZDg2FFsy>{-*VTLF@D8ez0{)#ow}iLWd0|~x&%cwYfA~bz zxdY!@_2$CcD+dogW^%PIK73=%Cx9QQdI;e=X`T^$iuwKve^+@X@Y{8+rSL=bxf%Qs z(|_O(n*I;(q&``~pEUjFqI&+@sjh7J9VUPH?#jW1cT`<@@LuZYKKx3pO8_sFTL|CB zeJ_A_)IJK~KWkq{@EtUt7~V~uz;`wMAKuyA|KVSasrGLU z-%Kie9vg#*+udDY;;d^RbGWc%VM>+g8)lUJxPw!R2AC_B}IM(m~TK)0AmeoV| z1RK6mc{=bXG>!{DX5T7L4{pz>+=n}+|HHefPD1#{?W=Jj_yDa-4DY3NOyK+LK9<6l zX#5PmT%N<9QC}+HZ)sgh_;aTJU+VmkyvcvA#3nhEC!6|*zohX!co*gD!{0H# z|G;lk-G=a<$}NKD`rH`4q3S$=-(${S_~xpU48DuzpTm#SzANCrscuX7be*Txzv}tF zYVwDluACkCR+^_v*L~H4->p1-_=%c-08f=q2;W|x8^L#!$M6o zJcECzI?3TZ7Pt6g`~tqcawy?PsD7+5_57bzKe6HOsIDCNZYFh6=y@CdigI({p7wraL`5&cu+VK6=9~^jpy{`)&qVYZWVW$4!>+8J& z_!FwD5Pq2MQ4!ozy~Xf8$}@p)tj|s1XPf&ce0%Mq9KN^uTLIrg`>}+7ylb_N)|K`A zSEz5;a8Khq@KSx)h4<3)9($?V}JrNc$*)uXSs650ByFw7(Mgsiywn zZ>Zm9@E`TQIlPa_AKp&uTf%#(POPiy`R}Opwc*zE>b)FzU)7-te^zzt!CxO;t-BAO zr{@FsyUHPipQ+p;_^-+*hQFsikigf|dZqAws)r0dLZ6$%cT;W!`~cl&O89)euQj2b z|K28lcyEp4z>inIa^a!rKk$w8zCQdDca)RMbE0R#u=-!%Edk5$eg{9S!+1n*U!Xpm!Z#gT^^FYvfu7IdTPdFcevG;Q!~2{3|6R}jcGZauFH~<1e1z8B zg>RsK>%j-Wfq$X*O5vxeKWFew^zAHAHG<9BY|J0`K0g*)h9Ff_Ubb^{6N)7 z0UxgSD&gmt`_IIB{-gA~4IieQ9r%CszApU2eXIKM;3t^#7d~3+6~JTV6T-);4kP$I z>Yp*ZkLo;uAFXpLg{K-PgCDK)E{C75JPY^@ntutuO7pj_ujfBh{n>^OlRNN@v|n8K zOwHeekI}mL@L$xg0{Ah?ErfU3vRdB=ezW#z48Kh0asnTtI#1#Kb#7+xU$q}|_)67b z0sl>2!e=WV>xO#%S1KPHKGNh5KUDk9h3}$#Jot{R96nP0p@3he`IPWjZcVD^ADR9GU#kA;z^~Ija^Y8+ z@4xVSm4gpILHjy@_c!$qU)xpv!`C^#@)*9i)+>R}RUM}AwVtoe{S5ADoE*Ns=2O5g zRbMLMC#erxH`en%N$YFFx7EGKfe+U6F1)S!k_R8FI``p2RfhrmTCHOUe^t3f@YW`O zc#Bn4o(X)S>M(_0t3HsyhbXrkK3UHf@XJm9@NuehYjQn*U;V^}pJ0A}hQFyCT=+?< zXAi!f>dJ>-qj?7KSbaN$-=_DC;48FGWB5a+|G+2db5r;b%|C-LQ9sP#y|gb1_zjwW z3ExC@V%=2F{}!FsHhhBC%YkpCJYD#$dM^*&QTxJ&FE_tGz_--*oe|aXscsASD%C>?Z*TISQqO-2%;Fd^$*`i-xEXliF)4%evopG;alsy68JE4{=x@o{0tsyU*zy}__6q7&v0Oje!r)u8?@IKntA^awD|A*f$kKsd=X9C|w z^H1T{P1XL&;3ugM=kQSHLIK}Nxs~vL=-jk!spr4Dseky?*Y)=ocwzcKytU3d58hSp z>%)IA{Re)G$sc~7<`cmm)c%U$`8}r;G1av8T?OUt98lY_iO(a@L%*^C47px zf8JWp|6Hx34ZleH$bpZQyYRIKSL@}$$EuI{@czmcmRw`LD0sYtYMsSo(@ z&N`O^_#LW~5Z=Y)58qhxkKx;#U)5~_cU8|Rd}qxkgAdg@=J2jM#|!vXs<)D^y0vbr z=RaNRYr_vP{U5%W*2RVY^Xlq-J@|Cx>BBeH_m=>EuGTk%-==zt;18>AWB3>9lL>rR zbN_*N)p}*{-pV1T>s%|~?NkpXe5UTh*6oh<`@dFy{I6y0p>?<6yQtnA_yx+@gc@ruMW5@zFVsEFhaai>3E)qtol89J{M_;tF^r|=otry1N)J?HSpO#g>}uk|Y7tL4_6_58=`y=?fuRnHE5j_SmP zzasbGSDN~V&(?kn;A6C2A-u2ZCxZV=`!R;^YWhF?TJ_-+exUYU20zyHANaGXlL9_j zl&vJ=Na=_*|_^2p^yvBKQ?1fA}m@ z|L`|dCn-T>F{5?G%!td7j5&U+oOALR;^dI;D^@kLGkH*R1uc{yB@YA*L3i#pX{sVtO z^Re!!=f9`+g$>_D=Yj+Ox6V@+zJuz=gTJBr@!`{Sjs);eO#bi(O#bkr^u95Ctm-O( z_t5*M@aNQLGWhWtKZl=e?*H(sO#Q=m?OD~EHNBpHpz&?^vFaxde7M%#g%2?O2mY?f zAAYL(Kmfl{`zwT>rg=v2Jyj<$yfFPA{-D-9gE4dj7M_?+@@o&pYs&W+;F72RdIo`1hv% z;isGLU+{y}A42$S%`<|pr*kBRKX3AfAEn$<_(8hwW$@9epB(2q!P)2astp6Z-(;pZ=FVg3HkgU?lNKKx+qqX3?m{sUjE^^M?rsjtTH!!>>a zzgy#{@JluS41T-zV-7!A{kDMT+NULan(n>U1IXW;zwjRB{Dm*lestlb*4=~8(K`C@ zqfGwrja1Je{8dx`@P4Z282+Z7PvD8^Kk$2$a|WNOdduM-D~AH!?WU?fl<>BCFYCd2 z{(VjT!(TD=4}V(cf(!4baXk2H(|_Q7weA5tRSqHiAk{+z|3ZB-hX2R(ANT{N{^4s~ zUhUruK1zKfhxb$c6!6Qnk4pI0nx~c4^PjEtwc)p`&pYsYO#g>3)cbnyMW+A2AJl#f z;CHJ&L-;_|c?ADRpBuwd%`<^NCQso@RL>dwss2?x=kWEkUIl!)#wp=*RJYcQdj9*V zf7*qXKd(BB;HPR`V)!cMnZP$v-KOxnlxGHi)AWD%1g(1k-{0g9Uu5!sxSs#kIu~sC z$LbpnyshT%!h7m-J@}c*$A{mq_YL5uYF~u#PMT)~pQ-aAhR>EK@N=~8Df|n)Zw7xv z^UUGzYhM)bgVj$;_#3AGJW|j9k}a$LX2Z|dJRSI{>ccL4C*|Y857&Hr_z0~_06#+O z7{ZUzI1&6(%`=AosQXv~U#6T>_~$xDGWeN#-yHs~_H_ZDsC`kwU()`y9#=(NpK2f3a8Khn@DZl|;ZN&c;lWQ(4nF*etE+t%z~9n3 zhVVJcErNfqdXC`(bsi<~j_RK&ysz@f;JuVX4sS7_s<#4ulHRw3_cQs=tmprp-q(gd zslMmHAJw_+!aM7|JowIXAO4lrJ%F!Po+12HAG{*C&ZHLITgX!T(m{-O4l1OG(p<-+Hf`iD=~{`KLbr&sk8z(<(# z7k-K68Nsa{)%(WqLj5^`FIR3U{7b!82ERn}%;7I-T?+Uw=Kc?#pnIM5IP%x~+VHhz zR{1#a%eJiE*M$$)x_j_Kb?C!C)A|PRQaOb1mdZJTzoNbr(^U@%{4(X4!ee;`Uwd%% zzBxQM`NM~p{sUi6d0J1@^M6D0wBcVUHwPY@{NXof{vLdl&TAjOzTPWL)4uGtD!Dx77GKyp6noZ=^m`!k4KYtf%Yw|7Px=@XNIB4*ZS2 z>i_VsHGdC2U+d_@zfd0t;Kyhmh45IpMey&;?{Dz_8Yh8|);>z%3pCFR9-I1ypQ*lA zz<*Jlm++s>{bzPP|4p=yZ1`qcUkASS*~%Y&uJ(loe^=|}!`rG(0{A*-SM?miFERZG zzO}}Q;RmXpC-CQW&rIR#>%B7gGSx{AzeVR=0guf66YgmLTF=z;zd?0n!#7Y44*X?v z|A%){4jz1v>d=R8r#=(Fzt=tu;UiRU5qzr7qZodn>LGy-)qGO;Ey^K-Ptp06!^bJ- z0)DglUJ3t?a_b>Qu_UtIVy-IqN0p{he4zUD<$od@v6nokJ7RCz}5 z`%M1uVW$7U@6&sw@L4)HGx(;e!yNvwseiby_buT+^{@Jd^=v)=b(Mn+|6cpffj^^p zy6`779}m9N^ndth)pGzZ)UQJL#_A6d{9BznG5k2?kiaLXZd3R~c?RFoQ^Pai|PN**YjVibM;;} zd|T81;Xi9%xbU4!|A$|ubJK@kqxA~lv7Qg%f6{y+_(jS&hJT@bl)&#)e@@}2X?-(z z2Xp^~-(mVc{MXm3zFNX<^%-kUJ^y<(9~-`fo_F9o=-hPSTkClbzEJ0m5AUk|8^Cu_ zorLh|dfy1X=0jEe#PIc0R|$MO<(a}eY5o~}SIskrpQZIG;2-IIOZX1@Tx)JU|90xD zHvC@o83(?`fa-l+_`1r$gLl*C`fywM1n@27A-t77H-hh}^@`!AnEns%rus?Y)73XJ z_zmX%4}VDc6z~l-&l0{$eb0KKp8v0M8$MS1+JP_AzINfU`lkoCwJtt7VyWlE+u?-^=IqFdj8*N zd>g*I=|Aur)Sq4W3%6GD_u#Jjwh!OS^dIumXQ(g5@Xb|+34A|&ZVJD_ zoWJm`G)@lxSnF88Z_zj<{9t{qHLsrkYTa{ecu%db1Mi{z?!ve3yw30CV|nn0##Zjb zmuUV0d>^fQ2yZdJTHgr%XRU7xpQUw4;E!uQDSUh7oWZYBAIRbRsGbY>YpTN%eyjGo z^-?|mPRh-OKcRb|1JAU-T=-vZV~)0)m04tKQ!*4qfNv){|LUh>MDk>c~tej z3H*MoR|gPH9I`yRjzLD0Ygdd>3YQ0*||2&;*Hhf*p-+|wx&voH{HT?%Z zPy5%0w>9+-|5^JbgkNaRU-+e3ml)nfc_#4rnokOUQGGRo@1k*X_%^D~0=|3aYTZlt zC#qZPwR-+*POSQX4PUJN>%d=7Uv=TH$vyZ9+Fw3=sm2fB>uNqB{B`9M!S7Rj#_+AQ zFB16c+FvRBaNSQbct_Pq4u3@ZsDSTd@`wMR{$Rac&;LI4RU1A-@8!TxQl2intLnjn zZ>Jo5cyH~;0KUKaa0u_L93uFU8YhO&Rv%8_Q*|Fm;cuJzhaaYMIfoys&n@74YQL25 zS<2IzU(f$b?F$>egK~4=J(Z6OAE5bo@E)3v4w8uV?`G;B z{;;|K!26o}4}4>dpToOr`~tqU?hhsWcJ*y5ujjwN#8I@V}~lQuyhbPX@Qu4|Di%Jzu~-Q2mtfEtH$} zpL+h6_pHtf8~%&>l>=X_@m=^8s%H0KSLTD})bG-;3b=RJSpFpge)M zQ$45fEtGQx|C`n;hyPpeTflp&o=f->fe&WJAY2SJ9H+A0m z@KL7z;d9luL-^LpCxTz2`ibF*=AXdd)IA}EcQX0I7wP#NzG8Z{uM2o@eQzq^tMt6} zW>js{7IerE__FmKYWqNAO5NONdTXuJVSWz&ecAO;E~obh99kZOW>jQ zQ3_wGeVxHODW4qvs_LYG->r2o;a}-}t+(p=pR4)U@MBH>@Hh3jE_{*PgYTyA#XkI0 z^@jj{tH~e!xcUAI-&g%AhCg8HAAX-(tz!ybUwtxzAE@zj_@f%XfFG$kDdFQ(C)V5b z{8wn*ZTJi3{t16g?!pgMU-IA|YybN2r!@ZnUaC$)_+46;2)?)0H-`JV&nNJWm2(O| z)7*dH$0*MnKEa&7@SU_@O1PtQ$68R&|2WOlhCi%2ap1eD&$#e*dM^)tqQ>{(JE`9W z@aMHIA>32W5qx)z6T>Gep9H?MzDK0+F3Kl^@2&UE;kzs60=`7`R>J?L-v_LB>iPel z+=gGMzU06&^#K>|X`UYZWRpMqE$yQK-b*=$@F!Fc5&Q)8`53;B)+K@Ot=v-hNg5}E zpRW1m@Q=qp0{U83K)-iy4 z$|r=k(dS0+CCVX&|EkYT;0I`3Qh0B92H(T{{s4bZ^;5u?nEc_(wJ)r9>-nE-@`t~q zKH$Jds871^Lv>Dh@IL1Jh5x8NAHa_>^$*`#{Vjs`(!Pu7TE_(bckTBSzFfIw@Yhu* zIed=3zZCHPntutuR`qEus^{Nd=Zg*hLGy9oN2*R-_^-;-gP*ST_2JK|p9JvX+V3HJ zp6NgE&9pCK_%E7&0w1pVq;OyLlfiSG@k@MO!G zzW>5oT%i6BAFTaV!doQj|L@oHKThjz!`Ih*9Qbyo|HF^fzVP5XDNi51OI*!AfDh0( zA^Z{5Lj)gc@`vxP&rRT8syuOIs6CRX9{?4Q~&T^%>C!1dj5TMPq5+b zP5$s9%d7Ww;m4WpzwpbHgAae#{Qe1Fdz$ix#~LSsUu60ZytURPfo~#D;ZyW|ErXBJ zd7Z=ejH`JT@OM;)CHx}w6RW7_f19a)`1{(w4*Wxn@4|bkt~~h3>gPWEba?>pq4x^m zq1HWu57#&`e5}?bf#0E=Q+R8gj~RR$)nN`lQT0~957PWg_*j$w$MyWDnf&25sNNj- zEpiwBpvLjwo9MlK_;lqEz^~FgLwI|Q6Ty$s{*B>Xm0JSusBu#G3{(H`AJh+Xc%*Zu zfS;>6Dd9($^Y;_S`u$(4KmOOU4%2$s@KdzD4!n=P@3`;_^tm4VL)~wE_|ckA0KZh@ zgz!(bA0zlNnokUWvS-yF68PmBKZTD|o*Dcr^Zg6n*YqEFf6b?akJ3K1K6U;`-sFGE z{HmYZ@T;_c9r%%U^{NpXU1)e4NH9;8WF~OZYG9W7cQ&{J&7$ z+VF2Re+Pb(*4KrfZSFtti%tIUwZ~QaD1fih=Z5gx^|=vzsOdj&U;8D2pJ(bHzP{#@ z!L2FPJahO0xAFpRb*Q|A_dlv~>+^d4Ej7LkUuo_?@C(fE5AX@92M_))J@3PxQ-2QN zgEY?&euc(~;CpFb$M6$$z9jJL)K^pZ#afpPzOmLNhfgr)FT9Dzm;b|*Le}b+o|tG@F{w)7=E0ofB231+!Q`Q@0-Cp z>%Nr3yNp}M`u$%4&-K0~eA4n3e>`t3asK$f=KQ@$^&trn_o%Ph@QK=A4*VqTYZv~TIe+0hoBKa}ou8_D2;h$DJcRFI?*H%)wZ1X@GkF3Z zsr5?X_vzfs;1A1lxTF1Ez(3HrP{M!Gea8B#p8qb|M>c$ja(3X)=$_!hH!$@NKT&AXnc|J1(7;QN~X1K(8pw1Cg)QN33Q zU#xYpme%usMbF#tE~-NZK1J{A!b7c>2T!%XeE1#e+X39sz7FAcoAVd`g6biLpR4&K z@Gh#`6h2e)%;2wS{2czZ_E!PlK>NCcf3Lo6eO=FgyzYlK{37jB2fnBFiwoaU_29v8 zQa|+J2db_Dco&mDe5vXuf*-1JV)*Tyt2#{JSL=OK_#3Lj41S9CZw}wZ^dI;X_3aYg zO8eUSrk?*Ds%INMQ2oJypP~7<@PoClJ^0~rAHIun4&e7Fw-A1+<`cp9)HpHR*SaL| z4V6O*e?a{zgZEIq^$#zULkwSQZPh<~hUS^VFEITdK1? zoy!5dv*sVdyJu!K)j-C94^ z^Pj8v*zn!8-yQf1%EyK8qvt*NA*yp9zC`a8z~^gyL-<5f|8Q41#PESy_XPe|%_oJ= z)jrDLYxJttC5IoZeN?~)n)^TedYvQI%6k5%YMwUy&w4Kh{-D;;g+Hb5BOd&3CV%)M z?e_rwu{?zTpT>#cXQMQ)~b5` z%T$Lp{593N1OHynyYN}MmwNCe>U%zXt^KO`1n~9bA^b6|djx;g^ndt%s-Fb@g!)nn z|GU;VgSS+kIs9OaU%(GD{U5$a{n`4dp8w6-7dE_&KG%V_(tdQ|r>Gu0`19HqKKyX) z-vEBr1=YHQ@Hdrn1m8&O6~nJkKTqJVn*I+z&EyY1Tl*`ApQYyu_=d`-g!k3DSU=bE zKS$%(@WW02f#0e1a^VM<{tsVn>Yr}<5BvZF9Vc>-qnn9BlZhI!7FMKdqw+zeN4bgO5=E^x>B)hXCGD z?-j!D*8C&*W%}G0ey{2zfp^yUDg5bstNT(0KU?*X!_U{c6!15-ze@NI=KlFhJ^#(r zXKeU++IJ3obJKs|$E!X)_<5SY4}ZqoKjFQ#k3#sr)lVY$$L9Mle4yr&z~?CE6#k6P zuMGZ{`TZIGi}Ebsi%kCTkLA{{_55E@4mSK_?IQ<%vGR1`9kh-f{1v^g4}U`*zz1r7 zh43S_E)o0%y^WAP(B5Gfu1kn@2cJ`Ya8qLf35!bU&|VA@`tadc{=byCV%(`8YhPTqH`^Qk5C<^@a3ld;r~&c2dKKy_=a zQO|#|=5NDa)4q1#qcwjQzOku)_|;lpAO5)3D}cYO-*rRyc&%duzgix{m#E(+@Jn@W zrtn)-&l&s+)msj~Uhh@F-_v0@V8XACHzi3Z>?3& z|1Fb0e0{B#1HV!C5Ep*3_Lm1gUGBpZjT6ATnf?RcSo4YC3r+s;Yp&4mZ}3U-6uwY> zCW9|kf5_ptYMcW8p2;76x8B!UyPp4<>SH#1syTn*%eAjv_+6Th2j9L|weNiR2z_n< zKlP_7w-Ek-<{!bo*L-65(}2i{ie<-*&kKX~vbHI5IzS@)R$ z{+yl<;rr`-BlvyVr!jn$-YcOihZO#S=|Ax4TE`szrPjTG|5f!?!hbNozqPFAzg+ic z8$L?);K08z^$-6<_3Xj#S6}ksr|Fyx;IZ~^2!BX@AcEhib&TOVs_!N6Qn{t@J#-() z;N3J%4)3TsEZ~#Wmr8gi?Q5%5J^vpy9~=HRt)l}Ut-kHT?^O;S+$yX6>%(tQ&H;R} z>M(>al}GSL?W(`U@ENB6z<*I4rf{cAHBJWKNx9|lweG9ltAO8X@`vA|_qEoo=fC## z)i^f%A?4}7Us8W?;mg(cJa}&U5ByiHdjP*n^AF+ssy-w5>Z6oDd_Copz#mq>O5u^| z|M0c`R*j#-FEQW0;Qwd(54^MXi?v=o|4Vcp+3=@SR}Or4)q@LPq5AaT>uLTzd?V!( zz`LjpL-<+hR}uX0dfyn{Q|CnjAE%sC_&FLsgHKi6=J4*ls&y&gv$XF@_<^b)YyEou zM`)flyv3|)UpVkXHI574S?lY;_mKPW`&H)w{4&);2!CGn5W(+LJ~4bB)ky-khE%zw z@Kxsgg&(baa=0}@{Ri$VpA!Cz*2QXF&;JMY4IAE4ecOTmtmj?$Bg)f*AD|q3_%5pR z0RDsS10nonlRvz*>Li9wP@O06jkF(A_@0_i27f%Ma?ateFH-*S!KVMfW7UgO(e?GaU9_2BbV4?cW=<{7|W)OkG2JDU23Z>)ah!!J;7 z0sLpxVF*7|`!Rwax1aKdf2jIN;O#V@6ke*2W$wJmeL$t4BxUcm};Gbz-Qux1A z4;lPZ)nN|rsPmhH~)WZFQgV;VpF!58(Hk`iE!gpAq~?_2C#kQtz9<|E)Sn;cYaZ z41S#UQ4Zf!&lm7Ex^I;56E%*tX+3{m{oIB>tNVikzfbGp!jI6pd+_C|A0NJp_G18l zc3f4rA$(6gAHg5id}8?N>H`UUW7T;IU-R?oewD#{=yP-UaMS5+ z(D{7t_Meq(9KZc*uMg1SX!koYGdD`z8{6ftqhtJpZ1$>k_f8md)uUcEw^Z!Nb zXv62Jt{nJ5+K(>$HJu9{{4hQ5!`FVV+V26pv+l7We0@D1!EaIB#_%!9ErFk?{*c0V z)p?r1x6r!h@H4c&1$>sy!4kfm>cnbW&%dwovEiA{H3zP$~l6+sC!WizsQ`w@C$V>O5x{f z{0x4fJcm!!zANBwnctt`-zjISeLesGs;+GK!6twBbE;<-p6Gn>;P+{sKKyPyAHd(! z{6qKxt#1S$tDIx_3))`^{1c6z!pCS`GWeHzK8L@g918f(>YpWi!39;FTU*xie_i!s z!{3%W@N2b?T=*X5_XqfSU8>LZ;SXzF0(gtOIu}B?tMfgAcQ(I2!_U?}O5mN;Pg3~d zs<#Z@Tl+MJKcM<4;EwJyCHw=`kJX``|4y2Z4S(D8fB3%2*@a)MoIUtes!t!Dt9}Cb zQOY5Nx7NBu@P0bKV)$acZvx+0>y^Ua*ZXGh1NFW+e0Swm!1vJjC48yLf2(@_hiZHq z?#mtcCd$EuAE)O%_zvd&3I9=jFMvOxeG$S}>E0N@7wa61;ayaR3H(vjZ3-W#bK_`xktS&c_&jojHHuziQo6_+<6f4E~PxX%4?h;}`IKv@c5dTY4|6V?F-^O#gwe z(0*~??`a$t{=Uu&559})(1$No-3IUzwU0u0Z_P7;pQk<_!}n8NCGZxvRp(0zKVE$= zgSXSYI*0G6_bT8&>z-4>*W5_wuT#(eRCE7_udC-B_%^2hz)vy#2Y#FC%7=fVbqwIP zJ~xCvul*ar7ib^F@FR6@Ch!mRdza-c`9-+tl+vL%G@T z5&B#Qeyu*&g@2_!4tt_H_(D*z_OxwOZd4zOVWI3%^+XEr%bg{Z+sZ*XNe-0earruAcw+F4g>Px<1!| zAEJK@* zwa$?OK3VHq!e2J`pY7}Ux72)W_>Zbv2fj+Vx$wu7vj_i=KG%m|t#uFJE7b==_yHSL zxkd2b^n48OY4V4UR$ooww<)&_?wIoz-bT3<@Xh2Ue5vZh>Qv9)8n60?pQm+q;74hH zx$w_apB{Xg-phv%P(KOa7wdCFcuUPQf*-58jp0X_{NYFH9+kp>)O|aHKdbK}IedUV zw}7v6Wp%$Q;T^OtR_A*D+sSSC(VD*l-$Bp2@NRMse!K3;KKwzgO8~!GeJ_L`Ywn-$ zU$swTy7ElmI?3Uq zO#Q?6(tW9fTMt+BvAWjtzh3#+@SEih{Cd@=3qQ-8zwoC`|A8N?^$OtoY5pO6gDb0j z9l=+b^A~=w#!29J>b+9<$tHjJJkx*R_h?@i@RQY7OS-xL{HdP*>3ZIVUt;e6@Zoyi zg@2@a^Wc|h93S3N^$@@#)l~@J#?(JNRSq${MGMtGysO4Z;a}-qoxyk2^Evz+)ms7I zOV5|^)3v_V4)y%^)%R!{K0x*9z_0I8y_XB`V*dUGAFj{!;jPtY0{H2wlMud(#*g5~ z>pl>}TbumhYiw1`KZT#9ewe|Z?p8gY!{=yU7x4W|{_r6h-`cUB|KZxFHvAQh@4)A1 zJ}x}e_#XVfsw*EpQ*|4_W9^p^K3mU6@KM^2G5iLNlfd85d!_JErvJd_oBjj0F09t2 zfbXd~Dd7t=j32LI9x1l~e!li~2)|Sw!P{v5 zG5kRD`!oDr)BoX{Xuo9eLp4qgw|=h9qXIt7{QdwRW%~cl_56Eiy=?dgS}zB_()|7a zKiAYhyp8VdK73Q1rvdyojUU3_P(4KOcjYnsX5AAK_$KOmDf~`7pTQ&TiyVHl`fve1 zd82Ayl<-3Hw05cI|GCah8~(28Kk)Xd6Bizt`iEbxy7l3=s6PbogH#V8yp{TP1aG5r zJcfUv_f6mrsyxD9-%xdB!?#hLJMhi*ybE8g_wwLd>3JW1mvRo^6I2f&e0x*>@QGUA7~Woe zCV@}X_$mAw^??k&oz^9XU#Natz>hcgA9(j`s=j1(tLMMJ+=frlJRSH1t)mP7&fNdu zQ_cM!-csjR0N+9H8^XuwdqD($O#LK=->Lqbz?W*@rSKiKz8QS(e!73c?^pd4@G)AK z628LRe|D?qznS`{4WFo-9r!AZA46QXa!!Rc;A< zH|3ndH`6^TgI}pUb9hhHZ2{j~Pyz{_59nY4sG~p>YomLg6hzPKVkBRZ=*io z!~1DI0sIcFR|x-E`zwM!ZR#I>mg)cSuIj5PUGvP~yXyHI{-)NqfbXhtO88!KYma*V z6P2e8pRODn_#C~j3%^74?7-le>dxZ^uPW#${d)i+vd{d3%!3V0&efWNQuK-@? z-W$RX*7Fg3veqSr-)rvw@L5`~6#k4ngMXp<ehzu zr}M&rXC{C6`O3$G->Z9|51*kv9KesttNj?l*V?UGuL!=LJcd7H?w{~B+D9qe);Jk_ zGu=;e_!8Am0Y6Inv4r2IK56Y;&%c}M!G<5Lb#dU+G>!|u)Z`C;QTy75&rn?j@MWg| z!%xtBBKQ_2fB5mrA%PE4KS|-K>N$g-q|eRaTkCTR__q3epo9<6ezf+f=O5_%nhoDl z=cxnVR_?-=sUAG|EY-OWe^Bcfz`Ls+Liqmj2!4vr_ZU9Z+<)L3st=^_&9pBv_%Q~&VSbzX$o@QY0Ufj^`7O5xj?{sRxx2Xc5P)BoW!b&izqAv#B_ztr=8O7;2wacQ67*G%XC z_lM|&(K{2p8@)ssiE`>kf z|G4k{UJvG-2YK*1=2)}lv(9y{wZE5G{tEjpk#9+zr1JY2CzCJEcjfYj!ucz|oB5aW zzcGF#KY=$HuBkiOaGCd$U3(2r9%GlRd{bFKb3h#YxnbCmHi&e*J7MR z{tWvll|MjknS5XBHkY5pdI)EKhAmA$}-8{rn%N55)4l=zEF$Y1TKD z-$*{0d@a^DmmkUZ7V?Ey_fozQ>t4y1;2a#tUu2%O{B^vMPs6?&%2%hZTKT=)t4H!p zxu10M6Irk52mSn?qTXV89{P`bN%BeMFNFRhU!Lc4`IGeXLjES_PANZ~`B(BYW*qmc zf&3hvujT7e4~_h|Q2+7+xKFn7L-3LO$Z-FZ7wn_xhyDDwX1!whCd@ODzfV4?{2cas zCO>@MaXz{HAM}Aj{sH^9lyAj+D)~Cp=Rp23^Q`4N^1Y4xXy!STPh?$M`Kr{_NdAxO z$A3TR^x6-#``F5fI$UkMCseFCb zH?tp2{mY~C#&uH2r^HM7ch(w@Q_1&X9S8EmsHo& z{tWe2%U{A9`F~lLq5KBs*~%w``@ej8>Zg+z?B8gEe*UYFTP&ZE`#>W9l6+G6=HdP+ zf1YzTmv6)Kh5RDUky3sq`?QkJ%J&ZB-;!r7zm)ZAI_~`J~6v z|K*z=J>I|3gns^)^S!ZriXV@kPvrNJLn?m+&*cAMALa6C)*6pr$Ui5CQa%qkSMt|b z-+_E8@~P#^abIoZtKdWVUes+XKbrnFlJ7#_?&KG8AB#5Z=l?|L|MIu_u0-C2-@oz` zm`^6(n*N!~XCR+Kz83qjluu1vRr1UDu7SMdT&U%5g#IJniTyZ~UrT+q@&&1fk$lgP zzkDs$H`=J5|6$BCmLEdDP2@}P-cb4LVg45Qp&$(K9&3p@*K$brw(iR#WRlkUL!w*c@E|4u^(IcDVz%<`R?qa zPQG5K|4sV&|BQLY^6AJkk#E8{sr)$BHcw{X9T<&*t*T+fO8f1IbO{PWO% zdkC-*fra+{X&}=X_Tw--kX~$xD17pNTwc z`6YZ;BR`vUAIk3w`O7zo)h_z^vP5{BlpQnJ`Hu4 z%g+w|NB&L7Uw#|wTgfk>KMdrDQ-`(uNbVJl{7TkkD4&DxYUNvn{N>-}-rmWtWS&vp z&wqZ#kLA~g`j=0>^|)`R@?-ekO#T)3kX%0dvE%+w$S42P*h~2znNKBOl|D9*&&T++ z{6gxyk2e}R9-(&n%KItLjIvL3qVf;=$HP1&| z_VZtw=VSSbcq0Ei{Qi>vf_qdZ|C;A>`CP1HAwQ1(R?62W&q}^9bv}^qN?)zzkI>H> z`6=Q4DPJV?A9?fhaUU4TzsGlV^2<&hKOb$?&wmEiC6?b!zfI&zQirL0vc<;ZXYylN zms~#Jdkgt_A%FRwL;sOa%XsZMbquvJckLkCy{6x;F zMt)hi|H%Ksy0`L2=&K|7fvj&QzlQOnZTk7Q?8jJsJ-H?FrP+_E{CnZ|ul$c8fBDgz zJB55x`b;UGjeT0lZ{oWK@-IUE@`>U8BVV3g1=h?$NgW{C^#O z|H>B)^)J7Wdt)m9P3Zsf)hCSmQZB#gb$Gs%-@&)0=e{Ll3BRDN^lKk}7$Z!Uk1 zbElBc&G(k_{m8SDFB|^;CSQa1*76_XjeKSH?@(Tb`j;;f?mzOUskcu47jlbs=;wbR zeI}N_$T*4oRO%#^|B-dimE?*N{j*w6n=?gO#>Rq8X5-$9+H@&%~dOui;{mCGNepA_=D zPaf~nQhpZeUdgv0&w>1@m&SddmcM{E@)g$_zjr8KnmTXg?~><8z8UM)$xqUk)CfO=@R%fAYVG%Kjk0MHyZhA^oOB* zH}YxavoimY{94wllOIogMnCT7e>D3vmOskAOXN?mPgD7`cqWgg7}s+yZM z`T3kvm3*y`zx)~YZ!N!#^=;(ykmpdoJbj~;Kg0Pol5b3%bn+?5Au9U$pUt|*@}1}# ziF`f2H4b-9N`yY};ck~)v&Z-o9Y--vNi`JVLQOg??6fB9-hj$ax??X~KBl)$+ST{mU=mJ}{JT!S}ZES^2J!ddrD4&Y& zYUR7rH%9UY=x?2TL+T{jv!DNa?3Y;n1ozuSeh_t=%9jo2uY9|Zzr16=7xG7$e<|OX zepSg2X1xaTrx>S}AHnmDe1-7uzw(^iTKTyX#_Kqe*YwFwemJ>BKk4UxHP6TL?Rak@ z-vv+Q(^6NNyyAOv`O2(UA+JOKkkiY!<^o^nXS$^-d@{2?M z@)_7KoqRSt+N+=cPNDzEf53ba`JCjC%17jo$y3gqTz&>Q6!P1bAJVUFaK$e5-K(m(Lse zzkE^No68?${)PMs>Z+8#LLFA}tI2sFzkwWT`7L-OUp@36`G(=|Z}J_;VI<#|bD@)e zPQQ)z>F2+1sDJs4oU@7iPUfG==ivEFejm^0@?}_;LcS2|SjyKSpGv+Y&kyAPV!zb# z*G}gAm3N$jL;1DTLo44k7zS_y>C!c8Fe*Sw>=dt{A=99>O6n=lnZ{U8F$-iNo zTt02M|HzjQ`O7DS{N<0Zz61F;)LSiIg?`w`TgDm6^HBftV>nMo@)Pk+{x9xn(SH5> zXCjAK{%pAa$hYJklFE;!e`fMOa&OG#4Ruw>=VU&md^>We=MA@2Y3 zx9Jb1{LRq+?_ z70WkgzbEqNLjRW+tZybiE#xmhh;yfqzsmTfe3wxF@-?W>f&6FGRW1KB`>~O48_r+( zW84#3`OZ8)l3%>ocwcn#y+ZvT(9eH0`fV&$!8=#eJ%Qrd^*m%=%9Z7pRm5Me2>uo zf?8`C!i@?VGkFMl}nANk*y|4_aqd-(wvs*ZyCxjW52iZQ^{c@KRo>Ym2brSqo4Kj{|$8#%U@ic{v&^x z{hrEaXMHpIv*eS@f6IFd`4-Hxlpn))Rr2rLGM?u^{*TcA<+o25Ki|ktWc;E0@bLE^ z`S&^ZNAh{t@16X2d~fvge*UkJPb{Bgzw!M%ktopmqe z>xBL<{~mQdkRQqYp_b3Z{2Tcu;rEyPeZH%epU!%XkjKRTqJ|L;Tn%YQ^2 zCh}j>A5!_R@Jzlx_sLxTF@3U-zZ>$GKS_VCAzkiUE?_E9eXh@1=gfN@IsjJJ$) zuH+YSehuWCh5L{E3)a1ne~*1Jly6RMt$Z8CAIZ1n`A$AD-2V^j=YJ+1%Qp}C%fFx= zQu*`LXC{xX8|RkGE9$3^UqHVq<>#?3mHZs~z(9T#=VmRRfqH1XCsF~eiG|a%J1RatmJ3# z{6Kye`?{9jk2mspPZ`(AQ2sT!wer`fw~>6;kiUFhzBf9epZ~So8)NzIA%FR`A%FQ| z?B7hjGy5@@@5}gwd?9iuSriFhs6 z-^qW*IT-z-pa1!x|HvEGC6T|)x~KA6*hiUsiTUV1^20;^^1qT>Dc_sAs^p8!G#-B- zzk?iV`9<`rM*dIkt3&yXta~f}1$mC-w^I+D{20DB`ei@=OGEzhC8@(ielOpZ%74s# zDU(;>{v-cCaxUZ#F@7nZBb>kTW!ZNF`A?WnEkB9*H1Y>0(0}CjkY_8OBGkY9yLcx* zFx)?n?B_q(3gh?2@@1*3M1IIwV)_IoFPkadiX>gRt3^$^SNq@N`6pHf$;{8sj9 zCjUEip3DCh{{ALEk$ZS4zmNG;@<;H2{K;_s%74!M8~L=<;ZVLa>)y)$O}`q+7vh}l zkNe=*d*d`iY|<&TE?m!D4kbn=;4-{_cr{wvdGV);`cfBEB!(SPLoky|ET zlks!;x$L__zDVdl@`gMs`Rn91kY7*EwftS4Z{#oVy+irZ%%_#_M;(sjYtr93`HA8D zt@`;dPkqMn|FXXl`9G-hRK6nf%;X>Oy}A4@`c)zSl=GsL-@-nvP0R`PdvejxuRbyCZpVgEMrAF@w}^0istR(>D#Gm>8(`j7ltJo;5X z|KnJ%SpE|8OysxI2U7XE;rEyPD9)W+-Y}m+K0W=mlqb|}CBHM=f8_Us{x9E%oE!PZ z%zr4qm_FIc|IGdx$*-fXI{Cr$=jgb8{*SPZu{;a)FF&0=mdfuVhfMxi=s)t~S(idS z#s9|VX(_**^{V7Y@LdD>8`MuNe?I*ELEdtY8p<~yhgN<$>oSu6i~ZQi7Y*m{@%{Wa z4gFu|9mv1SI@a=s8K;rY z^5l5khw>+QzLhUXA0El?3H?WYGy5Vsp`ZVM$t{*Yw$?bGM7}-Wo60NdFq6MW9p>_a zaSHis)MqLG4|P?^f5rJVkk3jVtL4v8SB?A!w~W7cDBn8Nzx)*5JCa|^zUbtWZ8#o3 zI{3Pn6 zkS`o^j&r1w|1k9bll%E! z&irHfW2}23zn14y`GTx(CSL;2<)4Q99$K!J?m%qsPh5U8A zl)uP4EBQ&xXCS|X9BTQuH;m`g$oC5OPx;5}msY;vE#rPZlE2IRJNc`eJJG~`{x8x` zVtLN^iTrcUg;ahj_sL8?O~_wTD!-lnklC3}F8?a@ANi!0 zjNe2wk$pOppU=76 z%J&TYM}8M|*va?f`RMe1{y!pzSbiVlBzEc{l^@LbnfxbwZ!X_}x-I0(abB15*F*o8 zFG^hv)5<4boc=F=mw9&bpD<2zMnC`c=Npd`%RdU|uYBdu zf8_2k#9;4L-|_Fvz5Qf zeP$&8AlyIY`*0tNe%;UiaOyUezZvfT@{d^GRQ`Cl|I06B|K{@9+3$sXz0iN;o8Xmv zRrbq3ej|OdmOsNh8~G#b_o2KDzklWPQ70q$ON`&im%VOW=h2{_|7P@oSpHe4fB8@8 zC#if*_C+SYm~$|fFUi&@C0~i}9mreiu$JG!ere?2`A+0n$iEHw%Wq&` zRPvv4uNcTTC5Kx6bDnSHzr=^~TX=6PKaP4H$$!N-oqTorTXar8|2r8!me0+4CGyGE z9=f^)W!-%lSN%BSUfTlpVC z|B?TVaXR@5d~bAaKmXaN+gQFX=V>CJm*-RY2S29&$fpneUp~j;^IwYj#PaLt8;N`o zzAKeKN59SFhclmCzB%7p$bUZ5IL}f(C;hgPFA(nk@?FFEE5DiVYUDrIaQxn(eCzqf z-pYT;JV)|h;hp?X?3d`ge*W8%LoDB$`6u${sKZo#M(98CS6P=_{w#f5t&*c+B|ChhQx|H%a@k-vFMgNh%&-1l>YtH3H{u^=|$~R^L#4bk?+dnvxfdJznJ+H@^u)$l%GgFRPx<; z??C=uIDh2_vacKYy)TdJYAEj*rs8AqDaPY8@-G-?C_gm({*v!Z z-yX^5=bY-~=P;k>qJI8+g#Is|g?tkERLnn>-y8n^Cf{wo@%QHP{djL7KQZJlzbMqd z{FTsu_7RBtIndA9>01(Z&7zf64mB^3CbbiTqbQ zpUP)oT{8J$A%A(a-*{aL`PuB3Qoav;rjnn+d zM)HHHt4^MCjzquh=RYs=iRFv1j}rOg%qNwfPTgkmr5Pue&%?P;$fsmoO8K^z(0}A* z=>PK1L;sf_K|YQA&5*zRnUKGHA#xkZui#wk>dd`GNcm=2Oex;y&ESw+Z)8`A&E%e~9yXBv05E zo%|f?GrF{&|Apc2Kk}o=jPlg<=;@xm3#r7AISG$ z-D~+Jytk3hM86u!pJ9Dl`Qp5HB!8cLI{D=9j?bN_?&p6I>k`Yq&%Q|H+ip1CFR6S9 z_Dd$;jrz&u@3Y?v`Q^-~lrP8lmHa*Gd>~(*zE{hyX8cBe1^2+A{5rgqzr?zXKkcSpG5Vn8;^koK$`p`zVv2z`n@kSJMv*`8=Wj%jcv%EBWK}fq{G{ z>ZF!G!}E>&4e}hyZ)BdWJR`S}e9_Q<`B43w#cq-qAI?v?O zvF~zu$@7K$CGsid`_WG-`OJ(zkZ;U9Yk9&tHu5lIzy&;M-d zFqZ!@!LVw8QSF&EY{1f_2AwPuNO8NDSQ_0r~|NbJsly$7-SB3sBKQiGH252%w&elx#Ea`~;CgN6KY`e!LWj{2t>hDwduTJ+⩾M3{Jx+6N}NZre2TNj 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

O== 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 g^ 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%0DqyI@pJ*@TCrvMIOau(gGKlb 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�o)aOR<>Dosz{9Dy|0)Iz2r|^ZUpA6nn^U2|} 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�?femr&9$h&a= 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

+hScAEH0@o67&4 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

uD8Og`)%cPp28dS2FwR_XBIoyOSwfHwo- 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

y(q&Ag)S%voB3f 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 z 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 literal 0 HcmV?d00001 diff --git a/vendor/github.com/DataDog/go-libddwaf/lib_dl.go b/vendor/github.com/DataDog/go-libddwaf/lib_dl.go new file mode 100644 index 000000000..64f63c4f0 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/lib_dl.go @@ -0,0 +1,88 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +// Purego only works on linux/macOS with amd64 and arm64 from now +//go:build (linux || darwin) && (amd64 || arm64) && !go1.22 + +package waf + +import ( + "fmt" + "reflect" + "unsafe" + + "github.com/ebitengine/purego" +) + +// libDl is created to wraps all interactions with the purego library +type libDl struct { + handle uintptr +} + +// dlOpen open a handle for the shared library `name`. +// the libLoader object is only a wrapped type for the linker handle +// the `loader` parameter must have tags in the form of `dlsym:` +// dlOpen will fill the object with symbols loaded from the library +// the struct of type `loader` must have a field of type `LibLoader` +// to be able to close the handle later +func dlOpen(name string, lib any) error { + handle, err := purego.Dlopen(name, purego.RTLD_GLOBAL|purego.RTLD_NOW) + if err != nil { + return fmt.Errorf("error opening shared library '%s'. Reason: %w", name, err) + } + + return dlOpenFromHandle(handle, lib) +} + +func dlOpenFromHandle(handle uintptr, lib any) error { + foundHandle := false + + libValue := reflect.ValueOf(lib).Elem() + libType := reflect.TypeOf(lib).Elem() + dl := libDl{handle: handle} + + for i := 0; i < libValue.NumField(); i++ { + fieldType := libType.Field(i) + + symbolName, ok := fieldType.Tag.Lookup("dlsym") + if ok { + symbol, err := purego.Dlsym(handle, symbolName) + if err != nil { + return fmt.Errorf("cannot load symbol '%s'. Reason: %w", symbolName, err) + } + + libValue.Field(i).Set(reflect.ValueOf(symbol)) + continue + } + + if fieldType.Type == reflect.TypeOf(dl) { + // Bypass the fact the reflect package doesn't allow writing to private struct fields by directly writing to the field's memory address ourselves + reflect.NewAt(reflect.TypeOf(dl), unsafe.Pointer(libValue.Field(i).UnsafeAddr())).Elem().Set(reflect.ValueOf(dl)) + foundHandle = true + } + } + + if !foundHandle { + return fmt.Errorf("could not find `libLoader` embedding to set the library handle, cowardly refusing the handle to be lost") + } + + return nil +} + +// syscall is the only way to make C calls with this interface. +// purego implementation limits the number of arguments to 9, it will panic if more are provided +// Note: `purego.SyscallN` has 3 return values: these are the following: +// +// 1st - The return value is a pointer or a int of any type +// 2nd - The return value is a float +// 3rd - The value of `errno` at the end of the call +func (lib *libDl) syscall(fn uintptr, args ...uintptr) uintptr { + ret, _, _ := purego.SyscallN(fn, args...) + return ret +} + +func (lib *libDl) Close() error { + return purego.Dlclose(lib.handle) +} diff --git a/vendor/github.com/DataDog/go-libddwaf/safe.go b/vendor/github.com/DataDog/go-libddwaf/safe.go new file mode 100644 index 000000000..de24bb51f --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/safe.go @@ -0,0 +1,68 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package waf + +import ( + "fmt" + "reflect" + "runtime" + + "github.com/pkg/errors" +) + +// PanicError is an error type wrapping a recovered panic value that happened +// during a function call. Such error must be considered unrecoverable and be +// used to try to gracefully abort. Keeping using this package after such an +// error is unreliable and the caller must rather stop using the library. +// Examples include safety checks errors. +type PanicError struct { + // The function symbol name that was given to `tryCall()`. + in string + // The recovered panic error while executing the function `in`. + Err error +} + +func newPanicError(in func() error, err error) *PanicError { + return &PanicError{ + in: runtime.FuncForPC(reflect.ValueOf(in).Pointer()).Name(), + Err: err, + } +} + +// Unwrap the error and return it. +// Required by errors.Is and errors.As functions. +func (e *PanicError) Unwrap() error { + return e.Err +} + +// Error returns the error string representation. +func (e *PanicError) Error() string { + return fmt.Sprintf("panic while executing %s: %#+v", e.in, e.Err) +} + +// tryCall calls function `f` and recovers from any panic occurring while it +// executes, returning it in a `PanicError` object type. +func tryCall(f func() error) (err error) { + defer func() { + r := recover() + if r == nil { + // Note that panic(nil) matches this case and cannot be really tested for. + return + } + + switch actual := r.(type) { + case error: + err = errors.WithStack(actual) + case string: + err = errors.New(actual) + default: + err = errors.Errorf("%v", r) + } + + err = newPanicError(f, err) + }() + return f() +} diff --git a/vendor/github.com/DataDog/go-libddwaf/symbols_linux_cgo.go b/vendor/github.com/DataDog/go-libddwaf/symbols_linux_cgo.go new file mode 100644 index 000000000..2675adb0e --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/symbols_linux_cgo.go @@ -0,0 +1,21 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build cgo && linux && !go1.22 + +package waf + +/* +// Needed otherwise cielf call is optimized away or the builtin version is used +#cgo CFLAGS: -O0 +#cgo LDFLAGS: -lm +float __attribute__((__noinline__)) ceilf(float arg); +*/ +import "C" + +// Required because libddwaf uses ceilf located in libm +// This forces CGO to link with libm, from there since +// libm is loaded, we can dlopen the waf without issues +var _ = C.ceilf(2.3) diff --git a/vendor/github.com/DataDog/go-libddwaf/symbols_linux_purego.go b/vendor/github.com/DataDog/go-libddwaf/symbols_linux_purego.go new file mode 100644 index 000000000..22e52dfef --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/symbols_linux_purego.go @@ -0,0 +1,15 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build !cgo && linux && !go1.22 + +package waf + +// Adds a dynamic import for libm.so because libddwaf needs the ceilf symbol +// This mechanic only works when CGO is not enabled +// +//go:cgo_import_dynamic purego_ceilf ceilf "libm.so.6" +//go:cgo_import_dynamic _ _ "libm.so.6" +var purego_ceilf uintptr diff --git a/vendor/github.com/DataDog/go-libddwaf/waf.go b/vendor/github.com/DataDog/go-libddwaf/waf.go new file mode 100644 index 000000000..d7dd53dcb --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/waf.go @@ -0,0 +1,130 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package waf + +import ( + "errors" + "fmt" + "sync" +) + +// UnsupportedTargetError is a wrapper error type helping to handle the error +// case of trying to execute this package on an unsupported target environment. +type UnsupportedTargetError struct { + error +} + +// Unwrap the error and return it. +// Required by errors.Is and errors.As functions. +func (e *UnsupportedTargetError) Unwrap() error { + return e.error +} + +// RulesetInfo stores the information - provided by the WAF - about WAF rules initialization. +type RulesetInfo struct { + // Number of rules successfully loaded + Loaded uint16 + // Number of rules which failed to parse + Failed uint16 + // Map from an error string to an array of all the rule ids for which + // that error was raised. {error: [rule_ids]} + Errors map[string][]string + // Ruleset version + Version string +} + +// Encoder/Decoder errors +var ( + errMaxDepth = errors.New("max depth reached") + errUnsupportedValue = errors.New("unsupported Go value") + errInvalidMapKey = errors.New("invalid WAF object map key") + errNilObjectPtr = errors.New("nil WAF object pointer") + errInvalidObjectType = errors.New("invalid type encountered when decoding") +) + +// RunError the WAF can return when running it. +type RunError int + +// Errors the WAF can return when running it. +const ( + ErrInternal RunError = iota + 1 + ErrInvalidObject + ErrInvalidArgument + ErrTimeout + ErrOutOfMemory + ErrEmptyRuleAddresses +) + +// Error returns the string representation of the RunError. +func (e RunError) Error() string { + switch e { + case ErrInternal: + return "internal waf error" + case ErrTimeout: + return "waf timeout" + case ErrInvalidObject: + return "invalid waf object" + case ErrInvalidArgument: + return "invalid waf argument" + case ErrOutOfMemory: + return "out of memory" + case ErrEmptyRuleAddresses: + return "empty rule addresses" + default: + return fmt.Sprintf("unknown waf error %d", e) + } +} + +// Globally dlopen() libddwaf only once because several dlopens (eg. in tests) +// aren't supported by macOS. +var ( + // libddwaf's dynamic library handle and entrypoints + wafLib *wafDl + // libddwaf's dlopen error if any + wafErr error + openWafOnce sync.Once +) + +// Load loads libddwaf's dynamic library. The dynamic library is opened only +// once by the first call to this function and internally stored globally, and +// no function is currently provided in this API to close the opened handle. +// Calling this function is not mandatory and is automatically performed by +// calls to NewHandle, the entrypoint of libddwaf, but Load is useful in order +// to explicitly check libddwaf's general health where calling NewHandle doesn't +// necessarily apply nor is doable. +// The function returns ok when libddwaf was successfully loaded, along with a +// non-nil error if any. Note that both ok and err can be set, meaning that +// libddwaf is usable but some non-critical errors happened, such as failures +// to remove temporary files. It is safe to continue using libddwaf in such +// case. +func Load() (ok bool, err error) { + openWafOnce.Do(func() { + wafLib, wafErr = newWafDl() + if wafErr != nil { + return + } + wafVersion = wafLib.wafGetVersion() + }) + + return wafLib != nil, wafErr +} + +// SupportsTarget returns true and a nil error when the target host environment +// is supported by this package and can be further used. +// Otherwise, it returns false along with an error detailing why. +func SupportsTarget() (bool, error) { + return supportsTarget() +} + +var wafVersion string + +// Version returns the version returned by libddwaf. +// It relies on the dynamic loading of the library, which can fail and return +// an empty string or the previously loaded version, if any. +func Version() string { + Load() + return wafVersion +} diff --git a/vendor/github.com/DataDog/go-libddwaf/waf_dl.go b/vendor/github.com/DataDog/go-libddwaf/waf_dl.go new file mode 100644 index 000000000..700251d30 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/waf_dl.go @@ -0,0 +1,176 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build (linux || darwin) && (amd64 || arm64) && !go1.22 + +package waf + +import ( + "fmt" + "os" +) + +// wafDl is the type wrapper for all C calls to the waf +// It uses `libwaf` to make C calls +// All calls must go through this one-liner to be type safe +// since purego calls are not type safe +type wafDl struct { + libDl + + Ddwaf_ruleset_info_free uintptr `dlsym:"ddwaf_ruleset_info_free"` + Ddwaf_init uintptr `dlsym:"ddwaf_init"` + Ddwaf_update uintptr `dlsym:"ddwaf_update"` + Ddwaf_destroy uintptr `dlsym:"ddwaf_destroy"` + Ddwaf_required_addresses uintptr `dlsym:"ddwaf_required_addresses"` + Ddwaf_get_version uintptr `dlsym:"ddwaf_get_version"` + Ddwaf_context_init uintptr `dlsym:"ddwaf_context_init"` + Ddwaf_context_destroy uintptr `dlsym:"ddwaf_context_destroy"` + Ddwaf_result_free uintptr `dlsym:"ddwaf_result_free"` + Ddwaf_run uintptr `dlsym:"ddwaf_run"` +} + +func dumpWafLibrary() (*os.File, error) { + file, err := os.CreateTemp("", "libddwaf-*.so") + if err != nil { + return nil, fmt.Errorf("Error creating temp file: %w", err) + } + + if err := os.WriteFile(file.Name(), libddwaf, 0400); err != nil { + return nil, fmt.Errorf("Error writing file: %w", err) + } + + return file, nil +} + +// newWafDl loads the libddwaf shared library along with all the needed symbols. +// The returned dynamic library handle dl can be non-nil even with a returned +// error, meaning that the dynamic library handle can be used but some errors +// happened in the last internal steps following the successful call to +// dlopen(). +func newWafDl() (dl *wafDl, err error) { + file, err := dumpWafLibrary() + if err != nil { + return nil, err + } + fName := file.Name() + defer func() { + rmErr := os.Remove(fName) + if rmErr != nil { + if err == nil { + err = rmErr + } else { + // TODO: rely on errors.Join() once go1.20 is our min supported Go version + err = fmt.Errorf("%w; along with an error while removing %s: %v", err, fName, rmErr) + } + } + }() + + var waf wafDl + if err := dlOpen(fName, &waf); err != nil { + return nil, fmt.Errorf("error while opening libddwaf library at %s: %w", fName, err) + } + defer func() { + closeErr := file.Close() + if closeErr != nil { + if err == nil { + err = closeErr + } else { + // TODO: rely on errors.Join() once go1.20 is our min supported Go version + err = fmt.Errorf("%w; along with an error while closing the shared libddwaf library file: %v", err, closeErr) + } + } + }() + + // Try calling the waf to make sure everything is fine + err = tryCall(func() error { + waf.wafGetVersion() + return nil + }) + if err != nil { + return nil, err + } + + return &waf, nil +} + +// wafGetVersion returned string is a static string so we do not need to free it +func (waf *wafDl) wafGetVersion() string { + return gostring(cast[byte](waf.syscall(waf.Ddwaf_get_version))) +} + +func (waf *wafDl) wafInit(ruleset *wafObject, config *wafConfig, info *wafRulesetInfo) wafHandle { + handle := wafHandle(waf.syscall(waf.Ddwaf_init, ptrToUintptr(ruleset), ptrToUintptr(config), ptrToUintptr(info))) + keepAlive(ruleset) + keepAlive(config) + keepAlive(info) + return handle +} + +func (waf *wafDl) wafUpdate(handle wafHandle, ruleset *wafObject, info *wafRulesetInfo) wafHandle { + newHandle := wafHandle(waf.syscall(waf.Ddwaf_update, uintptr(handle), ptrToUintptr(ruleset), ptrToUintptr(info))) + keepAlive(ruleset) + keepAlive(info) + return newHandle +} + +func (waf *wafDl) wafRulesetInfoFree(info *wafRulesetInfo) { + waf.syscall(waf.Ddwaf_ruleset_info_free, ptrToUintptr(info)) + keepAlive(info) +} + +func (waf *wafDl) wafDestroy(handle wafHandle) { + waf.syscall(waf.Ddwaf_destroy, uintptr(handle)) + keepAlive(handle) +} + +// wafRequiredAddresses returns static strings so we do not need to free them +func (waf *wafDl) wafRequiredAddresses(handle wafHandle) []string { + var nbAddresses uint32 + + arrayVoidC := waf.syscall(waf.Ddwaf_required_addresses, uintptr(handle), ptrToUintptr(&nbAddresses)) + if arrayVoidC == 0 { + return nil + } + + addresses := make([]string, int(nbAddresses)) + for i := 0; i < int(nbAddresses); i++ { + addresses[i] = gostring(*castWithOffset[*byte](arrayVoidC, uint64(i))) + } + + keepAlive(&nbAddresses) + keepAlive(handle) + + return addresses +} + +func (waf *wafDl) wafContextInit(handle wafHandle) wafContext { + ctx := wafContext(waf.syscall(waf.Ddwaf_context_init, uintptr(handle))) + keepAlive(handle) + return ctx +} + +func (waf *wafDl) wafContextDestroy(context wafContext) { + waf.syscall(waf.Ddwaf_context_destroy, uintptr(context)) + keepAlive(context) +} + +func (waf *wafDl) wafResultFree(result *wafResult) { + waf.syscall(waf.Ddwaf_result_free, ptrToUintptr(result)) + keepAlive(result) +} + +func (waf *wafDl) wafRun(context wafContext, obj *wafObject, result *wafResult, timeout uint64) wafReturnCode { + rc := wafReturnCode(waf.syscall(waf.Ddwaf_run, uintptr(context), ptrToUintptr(obj), ptrToUintptr(result), uintptr(timeout))) + keepAlive(context) + keepAlive(obj) + keepAlive(result) + keepAlive(timeout) + return rc +} + +// Implement SupportsTarget() +func supportsTarget() (bool, error) { + return true, nil +} diff --git a/vendor/github.com/DataDog/go-libddwaf/waf_dl_unsupported.go b/vendor/github.com/DataDog/go-libddwaf/waf_dl_unsupported.go new file mode 100644 index 000000000..af6739732 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/waf_dl_unsupported.go @@ -0,0 +1,58 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +// Build when the target OS or architecture are not supported +//go:build (!linux && !darwin) || (!amd64 && !arm64) || go1.22 + +package waf + +type wafDl struct{} + +func newWafDl() (dl *wafDl, err error) { + return nil, unsupportedTargetErr +} + +func (waf *wafDl) wafGetVersion() string { + return "" +} + +func (waf *wafDl) wafInit(obj *wafObject, config *wafConfig, info *wafRulesetInfo) wafHandle { + return 0 +} + +func (waf *wafDl) wafUpdate(handle wafHandle, ruleset *wafObject, info *wafRulesetInfo) wafHandle { + return 0 +} + +func (waf *wafDl) wafRulesetInfoFree(info *wafRulesetInfo) { +} + +func (waf *wafDl) wafDestroy(handle wafHandle) { +} + +func (waf *wafDl) wafRequiredAddresses(handle wafHandle) []string { + return nil +} + +func (waf *wafDl) wafContextInit(handle wafHandle) wafContext { + return 0 +} + +func (waf *wafDl) wafContextDestroy(context wafContext) { +} + +func (waf *wafDl) wafResultFree(result *wafResult) { +} + +func (waf *wafDl) wafRun(context wafContext, obj *wafObject, result *wafResult, timeout uint64) wafReturnCode { + return wafErrInternal +} + +// Implement SupportsTarget() +func supportsTarget() (bool, error) { + // TODO: provide finer-grained unsupported target error message giving the + // exact reason why + return false, unsupportedTargetErr +} diff --git a/vendor/github.com/DataDog/go-libddwaf/waf_unsupported_go.go b/vendor/github.com/DataDog/go-libddwaf/waf_unsupported_go.go new file mode 100644 index 000000000..122684708 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/waf_unsupported_go.go @@ -0,0 +1,17 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +// Supported OS/Arch but unsupported Go version +// Supported OS Supported Arch Bad Go Version +//go:build (linux || darwin || windows) && (amd64 || arm64) && go1.22 + +package waf + +import ( + "fmt" + "runtime" +) + +var unsupportedTargetErr = &UnsupportedTargetError{fmt.Errorf("the Go version %s is not supported", runtime.Version())} diff --git a/vendor/github.com/DataDog/go-libddwaf/waf_unsupported_target.go b/vendor/github.com/DataDog/go-libddwaf/waf_unsupported_target.go new file mode 100644 index 000000000..59648a7a3 --- /dev/null +++ b/vendor/github.com/DataDog/go-libddwaf/waf_unsupported_target.go @@ -0,0 +1,17 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +// Unsupported target OS or architecture on a supported Go version +// Unsupported OS Unsupported Arch Good Go Version +//go:build ((!linux && !darwin) || (!amd64 && !arm64)) && !go1.22 + +package waf + +import ( + "fmt" + "runtime" +) + +var unsupportedTargetErr = &UnsupportedTargetError{fmt.Errorf("the target operating-system %s or architecture %s are not supported", runtime.GOOS, runtime.GOARCH)} diff --git a/vendor/github.com/DataDog/go-tuf/LICENSE b/vendor/github.com/DataDog/go-tuf/LICENSE new file mode 100644 index 000000000..38163dd4b --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2014-2020 Prime Directive, Inc. 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 Prime Directive, Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/DataDog/go-tuf/client/client.go b/vendor/github.com/DataDog/go-tuf/client/client.go new file mode 100644 index 000000000..b364648e7 --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/client/client.go @@ -0,0 +1,982 @@ +package client + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "errors" + "io" + + "github.com/DataDog/go-tuf/data" + "github.com/DataDog/go-tuf/internal/roles" + "github.com/DataDog/go-tuf/util" + "github.com/DataDog/go-tuf/verify" +) + +const ( + // This is the upper limit in bytes we will use to limit the download + // size of the root/timestamp roles, since we might not don't know how + // big it is. + defaultRootDownloadLimit = 512000 + defaultTimestampDownloadLimit = 16384 + defaultMaxDelegations = 32 + defaultMaxRootRotations = 1e3 +) + +// LocalStore is local storage for downloaded top-level metadata. +type LocalStore interface { + io.Closer + + // GetMeta returns top-level metadata from local storage. The keys are + // in the form `ROLE.json`, with ROLE being a valid top-level role. + GetMeta() (map[string]json.RawMessage, error) + + // SetMeta persists the given top-level metadata in local storage, the + // name taking the same format as the keys returned by GetMeta. + SetMeta(name string, meta json.RawMessage) error + + // DeleteMeta deletes a given metadata. + DeleteMeta(name string) error +} + +// RemoteStore downloads top-level metadata and target files from a remote +// repository. +type RemoteStore interface { + // GetMeta downloads the given metadata from remote storage. + // + // `name` is the filename of the metadata (e.g. "root.json") + // + // `err` is ErrNotFound if the given file does not exist. + // + // `size` is the size of the stream, -1 indicating an unknown length. + GetMeta(name string) (stream io.ReadCloser, size int64, err error) + + // GetTarget downloads the given target file from remote storage. + // + // `path` is the path of the file relative to the root of the remote + // targets directory (e.g. "/path/to/file.txt"). + // + // `err` is ErrNotFound if the given file does not exist. + // + // `size` is the size of the stream, -1 indicating an unknown length. + GetTarget(path string) (stream io.ReadCloser, size int64, err error) +} + +// Client provides methods for fetching updates from a remote repository and +// downloading remote target files. +type Client struct { + local LocalStore + remote RemoteStore + + // The following four fields represent the versions of metatdata either + // from local storage or from recently downloaded metadata + rootVer int64 + targetsVer int64 + snapshotVer int64 + timestampVer int64 + + // targets is the list of available targets, either from local storage + // or from recently downloaded targets metadata + targets data.TargetFiles + + // localMeta is the raw metadata from local storage and is used to + // check whether remote metadata is present locally + localMeta map[string]json.RawMessage + + // db is a key DB used for verifying metadata + db *verify.DB + + // consistentSnapshot indicates whether the remote storage is using + // consistent snapshots (as specified in root.json) + consistentSnapshot bool + + // MaxDelegations limits by default the number of delegations visited for any + // target + MaxDelegations int + + // MaxRootRotations limits the number of downloaded roots in 1.0.19 root updater + MaxRootRotations int +} + +func NewClient(local LocalStore, remote RemoteStore) *Client { + return &Client{ + local: local, + remote: remote, + MaxDelegations: defaultMaxDelegations, + MaxRootRotations: defaultMaxRootRotations, + } +} + +// Init initializes a local repository from root metadata. +// +// The root's keys are extracted from the root and saved in local storage. +// Root expiration is not checked. +// It is expected that rootJSON was securely distributed with the software +// being updated. +func (c *Client) Init(rootJSON []byte) error { + err := c.loadAndVerifyRootMeta(rootJSON, true /*ignoreExpiredCheck*/) + if err != nil { + return err + } + return c.local.SetMeta("root.json", rootJSON) +} + +// Update downloads and verifies remote metadata and returns updated targets. +// It always performs root update (5.2 and 5.3) section of the v1.0.19 spec. +// +// https://theupdateframework.github.io/specification/v1.0.19/index.html#load-trusted-root +func (c *Client) Update() (data.TargetFiles, error) { + if err := c.UpdateRoots(); err != nil { + if _, ok := err.(verify.ErrExpired); ok { + // For backward compatibility, we wrap the ErrExpired inside + // ErrDecodeFailed. + return nil, ErrDecodeFailed{"root.json", err} + } + return nil, err + } + + // Load trusted metadata files, if any, and verify them against the latest root + c.getLocalMeta() + + // 5.4.1 - Download the timestamp metadata + timestampJSON, err := c.downloadMetaUnsafe("timestamp.json", defaultTimestampDownloadLimit) + if err != nil { + return nil, err + } + // 5.4.(2,3 and 4) - Verify timestamp against various attacks + // Returns the extracted snapshot metadata + snapshotMeta, sameTimestampVersion, err := c.decodeTimestamp(timestampJSON) + if sameTimestampVersion { + // The new timestamp.json file had the same version; we don't need to + // update, so bail early. + return c.targets, nil + } + + if err != nil { + return nil, err + } + // 5.4.5 - Persist the timestamp metadata + if err := c.local.SetMeta("timestamp.json", timestampJSON); err != nil { + return nil, err + } + + // 5.5.1 - Download snapshot metadata + // 5.5.2 and 5.5.4 - Check against timestamp role's snapshot hash and version + snapshotJSON, err := c.downloadMetaFromTimestamp("snapshot.json", snapshotMeta) + if err != nil { + return nil, err + } + // 5.5.(3,5 and 6) - Verify snapshot against various attacks + // Returns the extracted metadata files + snapshotMetas, err := c.decodeSnapshot(snapshotJSON) + if err != nil { + return nil, err + } + // 5.5.7 - Persist snapshot metadata + if err := c.local.SetMeta("snapshot.json", snapshotJSON); err != nil { + return nil, err + } + + // If we don't have the targets.json, download it, determine updated + // targets and save targets.json in local storage + var updatedTargets data.TargetFiles + targetsMeta := snapshotMetas["targets.json"] + if !c.hasMetaFromSnapshot("targets.json", targetsMeta) { + // 5.6.1 - Download the top-level targets metadata file + // 5.6.2 and 5.6.4 - Check against snapshot role's targets hash and version + targetsJSON, err := c.downloadMetaFromSnapshot("targets.json", targetsMeta) + if err != nil { + return nil, err + } + // 5.6.(3 and 5) - Verify signatures and check against freeze attack + updatedTargets, err = c.decodeTargets(targetsJSON) + if err != nil { + return nil, err + } + // 5.6.6 - Persist targets metadata + if err := c.local.SetMeta("targets.json", targetsJSON); err != nil { + return nil, err + } + } + + return updatedTargets, nil +} + +func (c *Client) UpdateRoots() error { + // https://theupdateframework.github.io/specification/v1.0.19/index.html#load-trusted-root + // 5.2 Load the trusted root metadata file. We assume that a good, + // trusted copy of this file was shipped with the package manager + // or software updater using an out-of-band process. + if err := c.loadAndVerifyLocalRootMeta( /*ignoreExpiredCheck=*/ true); err != nil { + return err + } + m, err := c.local.GetMeta() + if err != nil { + return err + } + + type KeyInfo struct { + KeyIDs map[string]bool + Threshold int + } + + // Prepare for 5.3.11: If the timestamp and / or snapshot keys have been rotated, + // then delete the trusted timestamp and snapshot metadata files. + getKeyInfo := func(role string) KeyInfo { + keyIDs := make(map[string]bool) + for k := range c.db.GetRole(role).KeyIDs { + keyIDs[k] = true + } + return KeyInfo{keyIDs, c.db.GetRole(role).Threshold} + } + + // The nonRootKeyInfo looks like this: + // { + // "timestamp": {KeyIDs={"KEYID1": true, "KEYID2": true}, Threshold=2}, + // "snapshot": {KeyIDs={"KEYID3": true}, Threshold=1}, + // "targets": {KeyIDs={"KEYID4": true, "KEYID5": true, "KEYID6": true}, Threshold=1} + // } + + nonRootKeyInfo := map[string]KeyInfo{"timestamp": {}, "snapshot": {}, "targets": {}} + for k := range nonRootKeyInfo { + nonRootKeyInfo[k] = getKeyInfo(k) + } + + // 5.3.1 Temorarily turn on the consistent snapshots in order to download + // versioned root metadata files as described next. + consistentSnapshot := c.consistentSnapshot + c.consistentSnapshot = true + + nRootMetadata := m["root.json"] + + // https://theupdateframework.github.io/specification/v1.0.19/index.html#update-root + + // 5.3.1 Since it may now be signed using entirely different keys, + // the client MUST somehow be able to establish a trusted line of + // continuity to the latest set of keys (see § 6.1 Key + // management and migration). To do so, the client MUST + // download intermediate root metadata files, until the + // latest available one is reached. Therefore, it MUST + // temporarily turn on consistent snapshots in order to + // download versioned root metadata files as described next. + + // This loop returns on error or breaks after downloading the lastest root metadata. + // 5.3.2 Let N denote the version number of the trusted root metadata file. + for i := 0; i < c.MaxRootRotations; i++ { + // 5.3.3 Try downloading version nPlusOne of the root metadata file. + // NOTE: as a side effect, we do update c.rootVer to nPlusOne between iterations. + nPlusOne := c.rootVer + 1 + nPlusOneRootPath := util.VersionedPath("root.json", nPlusOne) + nPlusOneRootMetadata, err := c.downloadMetaUnsafe(nPlusOneRootPath, defaultRootDownloadLimit) + + if err != nil { + if _, ok := err.(ErrMissingRemoteMetadata); ok { + // stop when the next root can't be downloaded + break + } + return err + } + + // 5.3.4 Check for an arbitrary software attack. + // 5.3.4.1 Check that N signed N+1 + nPlusOneRootMetadataSigned, err := c.verifyRoot(nRootMetadata, nPlusOneRootMetadata) + if err != nil { + return err + } + + // 5.3.4.2 check that N+1 signed itself. + if _, err := c.verifyRoot(nPlusOneRootMetadata, nPlusOneRootMetadata); err != nil { + // 5.3.6 Note that the expiration of the new (intermediate) root + // metadata file does not matter yet, because we will check for + // it in step 5.3.10. + return err + } + + // 5.3.5 Check for a rollback attack. Here, we check that nPlusOneRootMetadataSigned.version == nPlusOne. + if nPlusOneRootMetadataSigned.Version != nPlusOne { + return verify.ErrWrongVersion{ + Given: nPlusOneRootMetadataSigned.Version, + Expected: nPlusOne, + } + } + + // 5.3.7 Set the trusted root metadata file to the new root metadata file. + c.rootVer = nPlusOneRootMetadataSigned.Version + // NOTE: following up on 5.3.1, we want to always have consistent snapshots on for the duration + // of root rotation. AFTER the rotation is over, we will set it to the value of the last root. + consistentSnapshot = nPlusOneRootMetadataSigned.ConsistentSnapshot + // 5.3.8 Persist root metadata. The client MUST write the file to non-volatile storage as FILENAME.EXT (e.g. root.json). + // NOTE: Internally, setMeta stores metadata in LevelDB in a persistent manner. + if err := c.local.SetMeta("root.json", nPlusOneRootMetadata); err != nil { + return err + } + nRootMetadata = nPlusOneRootMetadata + // 5.3.9 Repeat steps 5.3.2 to 5.3.9 + + } // End of the for loop. + + // 5.3.10 Check for a freeze attack. + // NOTE: This will check for any, including freeze, attack. + if err := c.loadAndVerifyLocalRootMeta( /*ignoreExpiredCheck=*/ false); err != nil { + return err + } + + countDeleted := func(s1 map[string]bool, s2 map[string]bool) int { + c := 0 + for k := range s1 { + if _, ok := s2[k]; !ok { + c++ + } + } + return c + } + + // 5.3.11 To recover from fast-forward attack, certain metadata files need + // to be deleted if a threshold of keys are revoked. + // List of metadata that should be deleted per role if a threshold of keys + // are revoked: + // (based on the ongoing PR: https://github.com/mnm678/specification/tree/e50151d9df632299ddea364c4f44fe8ca9c10184) + // timestamp -> delete timestamp.json + // snapshot -> delete timestamp.json and snapshot.json + // targets -> delete snapshot.json and targets.json + // + // nonRootKeyInfo contains the keys and thresholds from root.json + // that were on disk before the root update process begins. + for topLevelRolename := range nonRootKeyInfo { + // ki contains the keys and thresholds from the latest downloaded root.json. + ki := getKeyInfo(topLevelRolename) + if countDeleted(nonRootKeyInfo[topLevelRolename].KeyIDs, ki.KeyIDs) >= nonRootKeyInfo[topLevelRolename].Threshold { + deleteMeta := map[string][]string{ + "timestamp": {"timestamp.json"}, + "snapshot": {"timestamp.json", "snapshot.json"}, + "targets": {"snapshot.json", "targets.json"}, + } + + for _, r := range deleteMeta[topLevelRolename] { + c.local.DeleteMeta(r) + } + } + } + + // 5.3.12 Set whether consistent snapshots are used as per the trusted root metadata file. + c.consistentSnapshot = consistentSnapshot + return nil +} + +// getLocalMeta decodes and verifies metadata from local storage. +// The verification of local files is purely for consistency, if an attacker +// has compromised the local storage, there is no guarantee it can be trusted. +// Before trying to load the metadata files, it clears the in-memory copy of the local metadata. +// This is to insure that all of the loaded metadata files at the end are indeed verified by the latest root. +// If some of the metadata files fail to load it will proceed with trying to load the rest, +// but still return an error at the end, if such occurred. Otherwise returns nil. +func (c *Client) getLocalMeta() error { + var retErr error + loadFailed := false + // Clear the in-memory copy of the local metadata. The goal is to reload and take into account + // only the metadata files that are verified by the latest root. Otherwise, their content should + // be ignored. + c.localMeta = make(map[string]json.RawMessage) + + // Load the latest root meta + if err := c.loadAndVerifyLocalRootMeta( /*ignoreExpiredCheck=*/ false); err != nil { + return err + } + + // Load into memory the existing meta, if any, from the local storage + meta, err := c.local.GetMeta() + if err != nil { + return nil + } + + // Verify the top-level metadata (timestamp, snapshot and targets) against the latest root and load it, if okay + if timestampJSON, ok := meta["timestamp.json"]; ok { + timestamp := &data.Timestamp{} + if err := c.db.UnmarshalTrusted(timestampJSON, timestamp, "timestamp"); err != nil { + loadFailed = true + retErr = err + } else { + c.localMeta["timestamp.json"] = meta["timestamp.json"] + c.timestampVer = timestamp.Version + } + } + + snapshot := &data.Snapshot{} + if snapshotJSON, ok := meta["snapshot.json"]; ok { + if err := c.db.UnmarshalTrusted(snapshotJSON, snapshot, "snapshot"); err != nil { + loadFailed = true + retErr = err + } else { + c.localMeta["snapshot.json"] = meta["snapshot.json"] + c.snapshotVer = snapshot.Version + } + } + + if targetsJSON, ok := meta["targets.json"]; ok { + targets := &data.Targets{} + if err := c.db.UnmarshalTrusted(targetsJSON, targets, "targets"); err != nil { + loadFailed = true + retErr = err + } else { + c.localMeta["targets.json"] = meta["targets.json"] + c.targetsVer = targets.Version + // FIXME(TUF-0.9) temporarily support files with leading path separators. + // c.targets = targets.Targets + c.loadTargets(targets.Targets) + } + } + + if loadFailed { + // If any of the metadata failed to be verified, return the reason for that failure + // and fail fast before delegated targets + return retErr + } + + // verifiedDelegatedTargets is a set of verified delegated targets + for fileName, fileContent := range meta { + if roles.IsDelegatedTargetsManifest(fileName) { + c.localMeta[fileName] = fileContent + } + } + + if loadFailed { + // If any of the metadata failed to be verified, return the reason for that failure + return retErr + } + return nil +} + +// getDelegationPathFromRaw verifies a delegated targets against +// a given snapshot and returns an error if it's invalid +// +// Delegation must have targets to get a path, else an empty list +// will be returned: this is because the delegation iterator is leveraged. +// +// Concrete example: +// targets +// └── a.json +//   └── b.json +//      └── c.json +//        └── target_file.txt +// +// If you try to use that function on "a.json" or "b.json", it'll return an empty list +// with no error, as neither of them declare a target file +// On the other hand, if you use that function on "c.json", it'll return & verify +// [c.json, b.json, a.json]. Running that function on every delegated targets +// guarantees that if a delegated targets is in the path of a target file, then it will +// appear at least once in the result +func (c *Client) getDelegationPathFromRaw(snapshot *data.Snapshot, delegatedTargetsJSON json.RawMessage) ([]string, error) { + // unmarshal the delegated targets first without verifying as + // we need at least one targets file name to leverage the + // getTargetFileMetaDelegationPath method + s := &data.Signed{} + if err := json.Unmarshal(delegatedTargetsJSON, s); err != nil { + return nil, err + } + targets := &data.Targets{} + if err := json.Unmarshal(s.Signed, targets); err != nil { + return nil, err + } + for targetPath := range targets.Targets { + // Gets target file from remote store + _, resp, err := c.getTargetFileMetaDelegationPath(targetPath, snapshot) + // We only need to test one targets file: + // - If it is valid, it means the delegated targets has been validated + // - If it is not, the delegated targets isn't valid + if errors.As(err, &ErrMissingRemoteMetadata{}) { + // As this function is used to fill the local store cache, the targets + // will be downloaded from the remote store as the local store cache is + // empty, meaning that the delegated targets may not exist anymore. In + // that case, ignore it. + return nil, nil + } + return resp, err + } + return nil, nil +} + +// loadAndVerifyLocalRootMeta decodes and verifies root metadata from +// local storage and loads the top-level keys. This method first clears +// the DB for top-level keys and then loads the new keys. +func (c *Client) loadAndVerifyLocalRootMeta(ignoreExpiredCheck bool) error { + meta, err := c.local.GetMeta() + if err != nil { + return err + } + rootJSON, ok := meta["root.json"] + if !ok { + return ErrNoRootKeys + } + return c.loadAndVerifyRootMeta(rootJSON, ignoreExpiredCheck) +} + +// loadAndVerifyRootMeta decodes and verifies root metadata and loads the top-level keys. +// This method first clears the DB for top-level keys and then loads the new keys. +func (c *Client) loadAndVerifyRootMeta(rootJSON []byte, ignoreExpiredCheck bool) error { + // unmarshal root.json without verifying as we need the root + // keys first + s := &data.Signed{} + if err := json.Unmarshal(rootJSON, s); err != nil { + return err + } + root := &data.Root{} + if err := json.Unmarshal(s.Signed, root); err != nil { + return err + } + ndb := verify.NewDB() + for id, k := range root.Keys { + if err := ndb.AddKey(id, k); err != nil { + return err + } + } + for name, role := range root.Roles { + if err := ndb.AddRole(name, role); err != nil { + return err + } + } + // Any trusted local root metadata version must be greater than 0. + if ignoreExpiredCheck { + if err := ndb.VerifyIgnoreExpiredCheck(s, "root", 0); err != nil { + return err + } + } else { + if err := ndb.Verify(s, "root", 0); err != nil { + return err + } + } + c.consistentSnapshot = root.ConsistentSnapshot + c.rootVer = root.Version + c.db = ndb + return nil +} + +// verifyRoot verifies Signed section of the bJSON +// using verification keys in aJSON. +func (c *Client) verifyRoot(aJSON []byte, bJSON []byte) (*data.Root, error) { + aSigned := &data.Signed{} + if err := json.Unmarshal(aJSON, aSigned); err != nil { + return nil, err + } + aRoot := &data.Root{} + if err := json.Unmarshal(aSigned.Signed, aRoot); err != nil { + return nil, err + } + + bSigned := &data.Signed{} + if err := json.Unmarshal(bJSON, bSigned); err != nil { + return nil, err + } + bRoot := &data.Root{} + if err := json.Unmarshal(bSigned.Signed, bRoot); err != nil { + return nil, err + } + + ndb := verify.NewDB() + for id, k := range aRoot.Keys { + if err := ndb.AddKey(id, k); err != nil { + return nil, err + } + } + for name, role := range aRoot.Roles { + if err := ndb.AddRole(name, role); err != nil { + return nil, err + } + } + + if err := ndb.VerifySignatures(bSigned, "root"); err != nil { + return nil, err + } + return bRoot, nil +} + +// FIXME(TUF-0.9) TUF is considering removing support for target files starting +// with a leading path separator. In order to be backwards compatible, we'll +// just remove leading separators for now. +func (c *Client) loadTargets(targets data.TargetFiles) { + c.targets = make(data.TargetFiles) + for name, meta := range targets { + c.targets[name] = meta + c.targets[util.NormalizeTarget(name)] = meta + } +} + +// downloadMetaUnsafe downloads top-level metadata from remote storage without +// verifying it's length and hashes (used for example to download timestamp.json +// which has unknown size). It will download at most maxMetaSize bytes. +func (c *Client) downloadMetaUnsafe(name string, maxMetaSize int64) ([]byte, error) { + r, size, err := c.remote.GetMeta(name) + if err != nil { + if IsNotFound(err) { + return nil, ErrMissingRemoteMetadata{name} + } + return nil, ErrDownloadFailed{name, err} + } + defer r.Close() + + // return ErrMetaTooLarge if the reported size is greater than maxMetaSize + if size > maxMetaSize { + return nil, ErrMetaTooLarge{name, size, maxMetaSize} + } + + // although the size has been checked above, use a LimitReader in case + // the reported size is inaccurate, or size is -1 which indicates an + // unknown length + return io.ReadAll(io.LimitReader(r, maxMetaSize)) +} + +// remoteGetFunc is the type of function the download method uses to download +// remote files +type remoteGetFunc func(string) (io.ReadCloser, int64, error) + +// downloadHashed tries to download the hashed prefixed version of the file. +func (c *Client) downloadHashed(file string, get remoteGetFunc, hashes data.Hashes) (io.ReadCloser, int64, error) { + // try each hashed path in turn, and either return the contents, + // try the next one if a 404 is returned, or return an error + for _, path := range util.HashedPaths(file, hashes) { + r, size, err := get(path) + if err != nil { + if IsNotFound(err) { + continue + } + return nil, 0, err + } + return r, size, nil + } + return nil, 0, ErrNotFound{file} +} + +// download downloads the given target file from remote storage using the get +// function, adding hashes to the path if consistent snapshots are in use +func (c *Client) downloadTarget(file string, get remoteGetFunc, hashes data.Hashes) (io.ReadCloser, int64, error) { + if c.consistentSnapshot { + return c.downloadHashed(file, get, hashes) + } else { + return get(file) + } +} + +// downloadVersionedMeta downloads top-level metadata from remote storage and +// verifies it using the given file metadata. +func (c *Client) downloadMeta(name string, version int64, m data.FileMeta) ([]byte, error) { + r, size, err := func() (io.ReadCloser, int64, error) { + if c.consistentSnapshot { + path := util.VersionedPath(name, version) + r, size, err := c.remote.GetMeta(path) + if err == nil { + return r, size, nil + } + + return nil, 0, err + } else { + return c.remote.GetMeta(name) + } + }() + if err != nil { + if IsNotFound(err) { + return nil, ErrMissingRemoteMetadata{name} + } + return nil, err + } + defer r.Close() + + // return ErrWrongSize if the reported size is known and incorrect + var stream io.Reader + if m.Length != 0 { + if size >= 0 && size != m.Length { + return nil, ErrWrongSize{name, size, m.Length} + } + + // wrap the data in a LimitReader so we download at most m.Length bytes + stream = io.LimitReader(r, m.Length) + } else { + stream = r + } + + return io.ReadAll(stream) +} + +func (c *Client) downloadMetaFromSnapshot(name string, m data.SnapshotFileMeta) ([]byte, error) { + b, err := c.downloadMeta(name, m.Version, data.FileMeta{Length: m.Length, Hashes: m.Hashes}) + if err != nil { + return nil, err + } + + // 5.6.2 – Check length and hashes of fetched bytes *before* parsing metadata + if err := util.BytesMatchLenAndHashes(b, m.Length, m.Hashes); err != nil { + return nil, ErrDownloadFailed{name, err} + } + + meta, err := util.GenerateSnapshotFileMeta(bytes.NewReader(b), m.Hashes.HashAlgorithms()...) + if err != nil { + return nil, err + } + + // 5.6.4 - Check against snapshot role's version + if err := util.VersionEqual(meta.Version, m.Version); err != nil { + return nil, ErrDownloadFailed{name, err} + } + + return b, nil +} + +func (c *Client) downloadMetaFromTimestamp(name string, m data.TimestampFileMeta) ([]byte, error) { + b, err := c.downloadMeta(name, m.Version, data.FileMeta{Length: m.Length, Hashes: m.Hashes}) + if err != nil { + return nil, err + } + + // 5.2.2. – Check length and hashes of fetched bytes *before* parsing metadata + if err := util.BytesMatchLenAndHashes(b, m.Length, m.Hashes); err != nil { + return nil, ErrDownloadFailed{name, err} + } + + meta, err := util.GenerateTimestampFileMeta(bytes.NewReader(b), m.Hashes.HashAlgorithms()...) + if err != nil { + return nil, err + } + + // 5.5.4 - Check against timestamp role's version + if err := util.VersionEqual(meta.Version, m.Version); err != nil { + return nil, ErrDownloadFailed{name, err} + } + + return b, nil +} + +// decodeSnapshot decodes and verifies snapshot metadata, and returns the new +// root and targets file meta. +func (c *Client) decodeSnapshot(b json.RawMessage) (data.SnapshotFiles, error) { + snapshot := &data.Snapshot{} + // 5.5.(3 and 6) - Verify it's signed correctly and it's not expired + if err := c.db.Unmarshal(b, snapshot, "snapshot", c.snapshotVer); err != nil { + return data.SnapshotFiles{}, ErrDecodeFailed{"snapshot.json", err} + } + // 5.5.5 - Check for top-level targets rollback attack + // Verify explicitly that current targets meta version is less than or equal to the new one + if snapshot.Meta["targets.json"].Version < c.targetsVer { + return data.SnapshotFiles{}, verify.ErrLowVersion{Actual: snapshot.Meta["targets.json"].Version, Current: c.targetsVer} + } + + // 5.5.5 - Get the local/trusted snapshot metadata, if any, and check all target metafiles against rollback attack + // In case the local snapshot metadata was not verified by the keys in the latest root during getLocalMeta(), + // snapshot.json won't be present in c.localMeta and thus this check will not be processed. + if snapshotJSON, ok := c.localMeta["snapshot.json"]; ok { + currentSnapshot := &data.Snapshot{} + if err := c.db.UnmarshalTrusted(snapshotJSON, currentSnapshot, "snapshot"); err != nil { + return data.SnapshotFiles{}, err + } + // 5.5.5 - Check for rollback attacks in both top-level and delegated targets roles (note that the Meta object includes both) + for path, local := range currentSnapshot.Meta { + if newMeta, ok := snapshot.Meta[path]; ok { + // 5.5.5 - Check for rollback attack + if newMeta.Version < local.Version { + return data.SnapshotFiles{}, verify.ErrLowVersion{Actual: newMeta.Version, Current: local.Version} + } + } else { + // 5.5.5 - Abort the update if a target file has been removed from the new snapshot file + return data.SnapshotFiles{}, verify.ErrMissingTargetFile + } + } + } + // At this point we can trust the new snapshot, the top-level targets, and any delegated targets versions it refers to + // so we can update the client's trusted versions and proceed with persisting the new snapshot metadata + // c.snapshotVer was already set when we verified the timestamp metadata + c.targetsVer = snapshot.Meta["targets.json"].Version + return snapshot.Meta, nil +} + +// decodeTargets decodes and verifies targets metadata, sets c.targets and +// returns updated targets. +func (c *Client) decodeTargets(b json.RawMessage) (data.TargetFiles, error) { + targets := &data.Targets{} + // 5.6.(3 and 5) - Verify signatures and check against freeze attack + if err := c.db.Unmarshal(b, targets, "targets", c.targetsVer); err != nil { + return nil, ErrDecodeFailed{"targets.json", err} + } + // Generate a list with the updated targets + updatedTargets := make(data.TargetFiles) + for path, meta := range targets.Targets { + if local, ok := c.targets[path]; ok { + if err := util.TargetFileMetaEqual(local, meta); err == nil { + continue + } + } + updatedTargets[path] = meta + } + // c.targetsVer was already updated when we verified the snapshot metadata + // FIXME(TUF-0.9) temporarily support files with leading path separators. + // c.targets = targets.Targets + c.loadTargets(targets.Targets) + return updatedTargets, nil +} + +// decodeTimestamp decodes and verifies timestamp metadata, and returns the +// new snapshot file meta and signals whether the update should be aborted early +// (the new timestamp has the same version as the old one, so there's no need to +// complete the update). +func (c *Client) decodeTimestamp(b json.RawMessage) (data.TimestampFileMeta, bool, error) { + timestamp := &data.Timestamp{} + + if err := c.db.Unmarshal(b, timestamp, "timestamp", c.timestampVer); err != nil { + return data.TimestampFileMeta{}, false, ErrDecodeFailed{"timestamp.json", err} + } + // 5.4.3.1 - Check for timestamp rollback attack + // We already checked for timestamp.Version < c.timestampVer in the Unmarshal call above. + // Here, we're checking for version equality, which indicates that we can abandon this update. + if timestamp.Version == c.timestampVer { + return data.TimestampFileMeta{}, true, nil + } + // 5.4.3.2 - Check for snapshot rollback attack + // Verify that the current snapshot meta version is less than or equal to the new one + if timestamp.Meta["snapshot.json"].Version < c.snapshotVer { + return data.TimestampFileMeta{}, false, verify.ErrLowVersion{Actual: timestamp.Meta["snapshot.json"].Version, Current: c.snapshotVer} + } + // At this point we can trust the new timestamp and the snapshot version it refers to + // so we can update the client's trusted versions and proceed with persisting the new timestamp + c.timestampVer = timestamp.Version + c.snapshotVer = timestamp.Meta["snapshot.json"].Version + return timestamp.Meta["snapshot.json"], false, nil +} + +// hasMetaFromSnapshot checks whether local metadata has the given meta +func (c *Client) hasMetaFromSnapshot(name string, m data.SnapshotFileMeta) bool { + _, ok := c.localMetaFromSnapshot(name, m) + return ok +} + +// localMetaFromSnapshot returns localmetadata if it matches the snapshot +func (c *Client) localMetaFromSnapshot(name string, m data.SnapshotFileMeta) (json.RawMessage, bool) { + b, ok := c.localMeta[name] + if !ok { + return nil, false + } + meta, err := util.GenerateSnapshotFileMeta(bytes.NewReader(b), m.Hashes.HashAlgorithms()...) + if err != nil { + return nil, false + } + err = util.SnapshotFileMetaEqual(meta, m) + return b, err == nil +} + +type Destination interface { + io.Writer + Delete() error +} + +// Download downloads the given target file from remote storage into dest. +// +// dest will be deleted and an error returned in the following situations: +// +// - The target does not exist in the local targets.json +// - Failed to fetch the chain of delegations accessible from local snapshot.json +// - The target does not exist in any targets +// - Metadata cannot be generated for the downloaded data +// - Generated metadata does not match local metadata for the given file +// - Size of the download does not match if the reported size is known and +// incorrect +func (c *Client) Download(name string, dest Destination) (err error) { + // delete dest if there is an error + defer func() { + if err != nil { + dest.Delete() + } + }() + + // populate c.targets from local storage if not set + if c.targets == nil { + if err := c.getLocalMeta(); err != nil { + return err + } + } + + normalizedName := util.NormalizeTarget(name) + localMeta, ok := c.targets[normalizedName] + if !ok { + // search in delegations + localMeta, err = c.getTargetFileMeta(normalizedName) + if err != nil { + return err + } + } + + // get the data from remote storage + r, size, err := c.downloadTarget(normalizedName, c.remote.GetTarget, localMeta.Hashes) + if err != nil { + return err + } + defer r.Close() + + // return ErrWrongSize if the reported size is known and incorrect + if size >= 0 && size != localMeta.Length { + return ErrWrongSize{name, size, localMeta.Length} + } + + // wrap the data in a LimitReader so we download at most localMeta.Length bytes + stream := io.LimitReader(r, localMeta.Length) + + // read the data, simultaneously writing it to dest and generating metadata + actual, err := util.GenerateTargetFileMeta(io.TeeReader(stream, dest), localMeta.HashAlgorithms()...) + if err != nil { + return ErrDownloadFailed{name, err} + } + + // check the data has the correct length and hashes + if err := util.TargetFileMetaEqual(actual, localMeta); err != nil { + if e, ok := err.(util.ErrWrongLength); ok { + return ErrWrongSize{name, e.Actual, e.Expected} + } + return ErrDownloadFailed{name, err} + } + + return nil +} + +func (c *Client) VerifyDigest(digest string, digestAlg string, length int64, path string) error { + localMeta, ok := c.targets[path] + if !ok { + return ErrUnknownTarget{Name: path, SnapshotVersion: c.snapshotVer} + } + + actual := data.FileMeta{Length: length, Hashes: make(data.Hashes, 1)} + var err error + actual.Hashes[digestAlg], err = hex.DecodeString(digest) + if err != nil { + return err + } + + if err := util.TargetFileMetaEqual(data.TargetFileMeta{FileMeta: actual}, localMeta); err != nil { + if e, ok := err.(util.ErrWrongLength); ok { + return ErrWrongSize{path, e.Actual, e.Expected} + } + return ErrDownloadFailed{path, err} + } + + return nil +} + +// Target returns the target metadata for a specific target if it +// exists, searching from top-level level targets then through +// all delegations. If it does not, ErrNotFound will be returned. +func (c *Client) Target(name string) (data.TargetFileMeta, error) { + target, err := c.getTargetFileMeta(util.NormalizeTarget(name)) + if err == nil { + return target, nil + } + + if _, ok := err.(ErrUnknownTarget); ok { + return data.TargetFileMeta{}, ErrNotFound{name} + } + + return data.TargetFileMeta{}, err +} + +// Targets returns the complete list of available top-level targets. +func (c *Client) Targets() (data.TargetFiles, error) { + // populate c.targets from local storage if not set + if c.targets == nil { + if err := c.getLocalMeta(); err != nil { + return nil, err + } + } + return c.targets, nil +} diff --git a/vendor/github.com/DataDog/go-tuf/client/delegations.go b/vendor/github.com/DataDog/go-tuf/client/delegations.go new file mode 100644 index 000000000..4cf540455 --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/client/delegations.go @@ -0,0 +1,152 @@ +package client + +import ( + "github.com/DataDog/go-tuf/data" + "github.com/DataDog/go-tuf/pkg/targets" + "github.com/DataDog/go-tuf/verify" +) + +// getTargetFileMeta searches for a verified TargetFileMeta matching a target +// Requires a local snapshot to be loaded and is locked to the snapshot versions. +func (c *Client) getTargetFileMeta(target string) (data.TargetFileMeta, error) { + snapshot, err := c.loadLocalSnapshot() + if err != nil { + return data.TargetFileMeta{}, err + } + + targetFileMeta, _, err := c.getTargetFileMetaDelegationPath(target, snapshot) + if err != nil { + return data.TargetFileMeta{}, err + } + return targetFileMeta, nil +} + +// getTargetFileMetaDelegationPath searches for a verified TargetFileMeta matching a target +// Requires snapshot to be passed and is locked to that specific snapshot versions. +// Searches through delegated targets following TUF spec 1.0.19 section 5.6. +func (c *Client) getTargetFileMetaDelegationPath(target string, snapshot *data.Snapshot) (data.TargetFileMeta, []string, error) { + // delegationsIterator covers 5.6.7 + // - pre-order depth-first search starting with the top targets + // - filter delegations with paths or path_hash_prefixes matching searched target + // - 5.6.7.1 cycles protection + // - 5.6.7.2 terminations + delegations, err := targets.NewDelegationsIterator(target, c.db) + if err != nil { + return data.TargetFileMeta{}, nil, err + } + + targetFileMeta := data.TargetFileMeta{} + delegationRole := "" + + for i := 0; i < c.MaxDelegations; i++ { + d, ok := delegations.Next() + if !ok { + return data.TargetFileMeta{}, nil, ErrUnknownTarget{target, snapshot.Version} + } + + // covers 5.6.{1,2,3,4,5,6} + targets, err := c.loadDelegatedTargets(snapshot, d.Delegatee.Name, d.DB) + if err != nil { + return data.TargetFileMeta{}, nil, err + } + + // stop when the searched TargetFileMeta is found + if m, ok := targets.Targets[target]; ok { + delegationRole = d.Delegatee.Name + targetFileMeta = m + break + } + + if targets.Delegations != nil { + delegationsDB, err := verify.NewDBFromDelegations(targets.Delegations) + if err != nil { + return data.TargetFileMeta{}, nil, err + } + err = delegations.Add(targets.Delegations.Roles, d.Delegatee.Name, delegationsDB) + if err != nil { + return data.TargetFileMeta{}, nil, err + } + } + } + + if len(delegationRole) > 0 { + return targetFileMeta, buildPath(delegations.Parent, delegationRole, ""), nil + } + + return data.TargetFileMeta{}, nil, ErrMaxDelegations{ + Target: target, + MaxDelegations: c.MaxDelegations, + SnapshotVersion: snapshot.Version, + } +} + +func buildPath(parent func(string) string, start string, end string) []string { + if start == end { + return nil + } + + path := []string{start} + current := start + for { + current = parent(current) + if current == end { + break + } + path = append(path, current) + } + return path +} + +func (c *Client) loadLocalSnapshot() (*data.Snapshot, error) { + if err := c.getLocalMeta(); err != nil { + return nil, err + } + rawS, ok := c.localMeta["snapshot.json"] + if !ok { + return nil, ErrNoLocalSnapshot + } + + snapshot := &data.Snapshot{} + if err := c.db.Unmarshal(rawS, snapshot, "snapshot", c.snapshotVer); err != nil { + return nil, ErrDecodeFailed{"snapshot.json", err} + } + return snapshot, nil +} + +// loadDelegatedTargets downloads, decodes, verifies and stores targets +func (c *Client) loadDelegatedTargets(snapshot *data.Snapshot, role string, db *verify.DB) (*data.Targets, error) { + var err error + fileName := role + ".json" + fileMeta, ok := snapshot.Meta[fileName] + if !ok { + return nil, ErrRoleNotInSnapshot{role, snapshot.Version} + } + + // 5.6.1 download target if not in the local store + // 5.6.2 check against snapshot hash + // 5.6.4 check against snapshot version + raw, alreadyStored := c.localMetaFromSnapshot(fileName, fileMeta) + if !alreadyStored { + raw, err = c.downloadMetaFromSnapshot(fileName, fileMeta) + if err != nil { + return nil, err + } + } + + targets := &data.Targets{} + // 5.6.3 verify signature with parent public keys + // 5.6.5 verify that the targets is not expired + // role "targets" is a top role verified by root keys loaded in the client db + err = db.Unmarshal(raw, targets, role, fileMeta.Version) + if err != nil { + return nil, ErrDecodeFailed{fileName, err} + } + + // 5.6.6 persist + if !alreadyStored { + if err := c.local.SetMeta(fileName, raw); err != nil { + return nil, err + } + } + return targets, nil +} diff --git a/vendor/github.com/DataDog/go-tuf/client/errors.go b/vendor/github.com/DataDog/go-tuf/client/errors.go new file mode 100644 index 000000000..3e7a5dcc4 --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/client/errors.go @@ -0,0 +1,107 @@ +package client + +import ( + "errors" + "fmt" +) + +var ( + ErrNoRootKeys = errors.New("tuf: no root keys found in local meta store") + ErrInsufficientKeys = errors.New("tuf: insufficient keys to meet threshold") + ErrNoLocalSnapshot = errors.New("tuf: no snapshot stored locally") +) + +type ErrMissingRemoteMetadata struct { + Name string +} + +func (e ErrMissingRemoteMetadata) Error() string { + return fmt.Sprintf("tuf: missing remote metadata %s", e.Name) +} + +type ErrDownloadFailed struct { + File string + Err error +} + +func (e ErrDownloadFailed) Error() string { + return fmt.Sprintf("tuf: failed to download %s: %s", e.File, e.Err) +} + +type ErrDecodeFailed struct { + File string + Err error +} + +func (e ErrDecodeFailed) Error() string { + return fmt.Sprintf("tuf: failed to decode %s: %s", e.File, e.Err) +} + +type ErrMaxDelegations struct { + Target string + MaxDelegations int + SnapshotVersion int64 +} + +func (e ErrMaxDelegations) Error() string { + return fmt.Sprintf("tuf: max delegation of %d reached searching for %s with snapshot version %d", e.MaxDelegations, e.Target, e.SnapshotVersion) +} + +type ErrNotFound struct { + File string +} + +func (e ErrNotFound) Error() string { + return fmt.Sprintf("tuf: file not found: %s", e.File) +} + +func IsNotFound(err error) bool { + _, ok := err.(ErrNotFound) + return ok +} + +type ErrWrongSize struct { + File string + Actual int64 + Expected int64 +} + +func (e ErrWrongSize) Error() string { + return fmt.Sprintf("tuf: unexpected file size: %s (expected %d bytes, got %d bytes)", e.File, e.Expected, e.Actual) +} + +type ErrUnknownTarget struct { + Name string + SnapshotVersion int64 +} + +func (e ErrUnknownTarget) Error() string { + return fmt.Sprintf("tuf: unknown target file: %s with snapshot version %d", e.Name, e.SnapshotVersion) +} + +type ErrMetaTooLarge struct { + Name string + Size int64 + MaxSize int64 +} + +func (e ErrMetaTooLarge) Error() string { + return fmt.Sprintf("tuf: %s size %d bytes greater than maximum %d bytes", e.Name, e.Size, e.MaxSize) +} + +type ErrInvalidURL struct { + URL string +} + +func (e ErrInvalidURL) Error() string { + return fmt.Sprintf("tuf: invalid repository URL %s", e.URL) +} + +type ErrRoleNotInSnapshot struct { + Role string + SnapshotVersion int64 +} + +func (e ErrRoleNotInSnapshot) Error() string { + return fmt.Sprintf("tuf: role %s not in snapshot version %d", e.Role, e.SnapshotVersion) +} diff --git a/vendor/github.com/DataDog/go-tuf/client/file_store.go b/vendor/github.com/DataDog/go-tuf/client/file_store.go new file mode 100644 index 000000000..520bbe73a --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/client/file_store.go @@ -0,0 +1,90 @@ +package client + +import ( + "bytes" + "errors" + "fmt" + "io" + "io/fs" +) + +// FileRemoteStore provides a RemoteStore interface compatible +// implementation that can be used where the RemoteStore is backed by a +// fs.FS. This is useful for example in air-gapped environments where there's no +// possibility to make outbound network connections. +// By having this be a fs.FS instead of directories allows the repository to +// be backed by something that's not persisted to disk. +func NewFileRemoteStore(fsys fs.FS, targetDir string) (*FileRemoteStore, error) { + if fsys == nil { + return nil, errors.New("nil fs.FS") + } + t := targetDir + if t == "" { + t = "targets" + } + // Make sure directory exists + d, err := fsys.Open(t) + if err != nil { + return nil, fmt.Errorf("failed to open targets directory %s: %w", t, err) + } + fi, err := d.Stat() + if err != nil { + return nil, fmt.Errorf("failed to stat targets directory %s: %w", t, err) + } + if !fi.IsDir() { + return nil, fmt.Errorf("targets directory not a directory %s", t) + } + + fsysT, err := fs.Sub(fsys, t) + if err != nil { + return nil, fmt.Errorf("failed to open targets directory %s: %w", t, err) + } + return &FileRemoteStore{fsys: fsys, targetDir: fsysT}, nil +} + +type FileRemoteStore struct { + // Meta directory fs + fsys fs.FS + // Target directory fs. + targetDir fs.FS + // In order to be able to make write operations (create, delete) we can't + // use fs.FS for it (it's read only), so we have to know the underlying + // directory that add/delete test methods can use. This is only necessary + // for testing purposes. + testDir string +} + +func (f *FileRemoteStore) GetMeta(name string) (io.ReadCloser, int64, error) { + rc, b, err := f.get(f.fsys, name) + return handleErrors(name, rc, b, err) +} + +func (f *FileRemoteStore) GetTarget(name string) (io.ReadCloser, int64, error) { + rc, b, err := f.get(f.targetDir, name) + return handleErrors(name, rc, b, err) +} + +func (f *FileRemoteStore) get(fsys fs.FS, s string) (io.ReadCloser, int64, error) { + if !fs.ValidPath(s) { + return nil, 0, fmt.Errorf("invalid path %s", s) + } + + b, err := fs.ReadFile(fsys, s) + if err != nil { + return nil, -1, err + } + return io.NopCloser(bytes.NewReader(b)), int64(len(b)), nil +} + +// handleErrors converts NotFound errors to something that TUF knows how to +// handle properly. For example, when looking for n+1 root files, this is a +// signal that it will stop looking. +func handleErrors(name string, rc io.ReadCloser, b int64, err error) (io.ReadCloser, int64, error) { + if err == nil { + return rc, b, err + } + if errors.Is(err, fs.ErrNotExist) { + return rc, b, ErrNotFound{name} + } + return rc, b, err +} diff --git a/vendor/github.com/DataDog/go-tuf/client/local_store.go b/vendor/github.com/DataDog/go-tuf/client/local_store.go new file mode 100644 index 000000000..bb9421f5d --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/client/local_store.go @@ -0,0 +1,29 @@ +package client + +import ( + "encoding/json" +) + +func MemoryLocalStore() LocalStore { + return make(memoryLocalStore) +} + +type memoryLocalStore map[string]json.RawMessage + +func (m memoryLocalStore) GetMeta() (map[string]json.RawMessage, error) { + return m, nil +} + +func (m memoryLocalStore) SetMeta(name string, meta json.RawMessage) error { + m[name] = meta + return nil +} + +func (m memoryLocalStore) DeleteMeta(name string) error { + delete(m, name) + return nil +} + +func (m memoryLocalStore) Close() error { + return nil +} diff --git a/vendor/github.com/DataDog/go-tuf/client/remote_store.go b/vendor/github.com/DataDog/go-tuf/client/remote_store.go new file mode 100644 index 000000000..17a63fc59 --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/client/remote_store.go @@ -0,0 +1,109 @@ +package client + +import ( + "fmt" + "io" + "net/http" + "net/url" + "path" + "strconv" + "strings" + "time" +) + +type HTTPRemoteOptions struct { + MetadataPath string + TargetsPath string + UserAgent string + Retries *HTTPRemoteRetries +} + +type HTTPRemoteRetries struct { + Delay time.Duration + Total time.Duration +} + +var DefaultHTTPRetries = &HTTPRemoteRetries{ + Delay: time.Second, + Total: 10 * time.Second, +} + +func HTTPRemoteStore(baseURL string, opts *HTTPRemoteOptions, client *http.Client) (RemoteStore, error) { + if !strings.HasPrefix(baseURL, "http") { + return nil, ErrInvalidURL{baseURL} + } + if opts == nil { + opts = &HTTPRemoteOptions{} + } + if opts.TargetsPath == "" { + opts.TargetsPath = "targets" + } + if client == nil { + client = http.DefaultClient + } + return &httpRemoteStore{baseURL, opts, client}, nil +} + +type httpRemoteStore struct { + baseURL string + opts *HTTPRemoteOptions + cli *http.Client +} + +func (h *httpRemoteStore) GetMeta(name string) (io.ReadCloser, int64, error) { + return h.get(path.Join(h.opts.MetadataPath, name)) +} + +func (h *httpRemoteStore) GetTarget(name string) (io.ReadCloser, int64, error) { + return h.get(path.Join(h.opts.TargetsPath, name)) +} + +func (h *httpRemoteStore) get(s string) (io.ReadCloser, int64, error) { + u := h.url(s) + req, err := http.NewRequest("GET", u, nil) + if err != nil { + return nil, 0, err + } + if h.opts.UserAgent != "" { + req.Header.Set("User-Agent", h.opts.UserAgent) + } + var res *http.Response + if r := h.opts.Retries; r != nil { + for start := time.Now(); time.Since(start) < r.Total; time.Sleep(r.Delay) { + res, err = h.cli.Do(req) + if err == nil && (res.StatusCode < 500 || res.StatusCode > 599) { + break + } + } + } else { + res, err = h.cli.Do(req) + } + if err != nil { + return nil, 0, err + } + + if res.StatusCode == http.StatusNotFound { + res.Body.Close() + return nil, 0, ErrNotFound{s} + } else if res.StatusCode != http.StatusOK { + res.Body.Close() + return nil, 0, &url.Error{ + Op: "GET", + URL: u, + Err: fmt.Errorf("unexpected HTTP status %d", res.StatusCode), + } + } + + size, err := strconv.ParseInt(res.Header.Get("Content-Length"), 10, 0) + if err != nil { + return res.Body, -1, nil + } + return res.Body, size, nil +} + +func (h *httpRemoteStore) url(path string) string { + if !strings.HasPrefix(path, "/") { + path = "/" + path + } + return h.baseURL + path +} diff --git a/vendor/github.com/DataDog/go-tuf/data/hex_bytes.go b/vendor/github.com/DataDog/go-tuf/data/hex_bytes.go new file mode 100644 index 000000000..ec200412e --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/data/hex_bytes.go @@ -0,0 +1,42 @@ +package data + +import ( + "crypto/sha256" + "encoding/hex" + "errors" +) + +type HexBytes []byte + +func (b *HexBytes) UnmarshalJSON(data []byte) error { + if len(data) < 2 || len(data)%2 != 0 || data[0] != '"' || data[len(data)-1] != '"' { + return errors.New("tuf: invalid JSON hex bytes") + } + res := make([]byte, hex.DecodedLen(len(data)-2)) + _, err := hex.Decode(res, data[1:len(data)-1]) + if err != nil { + return err + } + *b = res + return nil +} + +func (b HexBytes) MarshalJSON() ([]byte, error) { + res := make([]byte, hex.EncodedLen(len(b))+2) + res[0] = '"' + res[len(res)-1] = '"' + hex.Encode(res[1:], b) + return res, nil +} + +func (b HexBytes) String() string { + return hex.EncodeToString(b) +} + +// 4.5. File formats: targets.json and delegated target roles: +// ...each target path, when hashed with the SHA-256 hash function to produce +// a 64-byte hexadecimal digest (HEX_DIGEST)... +func PathHexDigest(s string) string { + b := sha256.Sum256([]byte(s)) + return hex.EncodeToString(b[:]) +} diff --git a/vendor/github.com/DataDog/go-tuf/data/types.go b/vendor/github.com/DataDog/go-tuf/data/types.go new file mode 100644 index 000000000..eb00489b6 --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/data/types.go @@ -0,0 +1,348 @@ +package data + +import ( + "bytes" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "path" + "strings" + "sync" + "time" + + "github.com/secure-systems-lab/go-securesystemslib/cjson" +) + +type KeyType string + +type KeyScheme string + +type HashAlgorithm string + +const ( + KeyIDLength = sha256.Size * 2 + + KeyTypeEd25519 KeyType = "ed25519" + // From version 1.0.32, the reference implementation defines 'ecdsa', + // not 'ecdsa-sha2-nistp256' for NIST P-256 curves. + KeyTypeECDSA_SHA2_P256 KeyType = "ecdsa" + KeyTypeECDSA_SHA2_P256_OLD_FMT KeyType = "ecdsa-sha2-nistp256" + KeyTypeRSASSA_PSS_SHA256 KeyType = "rsa" + + KeySchemeEd25519 KeyScheme = "ed25519" + KeySchemeECDSA_SHA2_P256 KeyScheme = "ecdsa-sha2-nistp256" + KeySchemeRSASSA_PSS_SHA256 KeyScheme = "rsassa-pss-sha256" + + HashAlgorithmSHA256 HashAlgorithm = "sha256" + HashAlgorithmSHA512 HashAlgorithm = "sha512" +) + +var ( + HashAlgorithms = []HashAlgorithm{HashAlgorithmSHA256, HashAlgorithmSHA512} + ErrPathsAndPathHashesSet = errors.New("tuf: failed validation of delegated target: paths and path_hash_prefixes are both set") +) + +type Signed struct { + Signed json.RawMessage `json:"signed"` + Signatures []Signature `json:"signatures"` +} + +type Signature struct { + KeyID string `json:"keyid"` + Signature HexBytes `json:"sig"` +} + +type PublicKey struct { + Type KeyType `json:"keytype"` + Scheme KeyScheme `json:"scheme"` + Algorithms []HashAlgorithm `json:"keyid_hash_algorithms,omitempty"` + Value json.RawMessage `json:"keyval"` + + ids []string + idOnce sync.Once +} + +type PrivateKey struct { + Type KeyType `json:"keytype"` + Scheme KeyScheme `json:"scheme,omitempty"` + Algorithms []HashAlgorithm `json:"keyid_hash_algorithms,omitempty"` + Value json.RawMessage `json:"keyval"` +} + +func (k *PublicKey) IDs() []string { + k.idOnce.Do(func() { + data, err := cjson.EncodeCanonical(k) + if err != nil { + panic(fmt.Errorf("tuf: error creating key ID: %w", err)) + } + digest := sha256.Sum256(data) + k.ids = []string{hex.EncodeToString(digest[:])} + }) + return k.ids +} + +func (k *PublicKey) ContainsID(id string) bool { + for _, keyid := range k.IDs() { + if id == keyid { + return true + } + } + return false +} + +func DefaultExpires(role string) time.Time { + var t time.Time + switch role { + case "root": + t = time.Now().AddDate(1, 0, 0) + case "snapshot": + t = time.Now().AddDate(0, 0, 7) + case "timestamp": + t = time.Now().AddDate(0, 0, 1) + default: + // targets and delegated targets + t = time.Now().AddDate(0, 3, 0) + } + return t.UTC().Round(time.Second) +} + +type Root struct { + Type string `json:"_type"` + SpecVersion string `json:"spec_version"` + Version int64 `json:"version"` + Expires time.Time `json:"expires"` + Keys map[string]*PublicKey `json:"keys"` + Roles map[string]*Role `json:"roles"` + Custom *json.RawMessage `json:"custom,omitempty"` + + ConsistentSnapshot bool `json:"consistent_snapshot"` +} + +func NewRoot() *Root { + return &Root{ + Type: "root", + SpecVersion: "1.0", + Expires: DefaultExpires("root"), + Keys: make(map[string]*PublicKey), + Roles: make(map[string]*Role), + ConsistentSnapshot: true, + } +} + +func (r *Root) AddKey(key *PublicKey) bool { + changed := false + for _, id := range key.IDs() { + if _, ok := r.Keys[id]; !ok { + changed = true + r.Keys[id] = key + } + } + return changed +} + +type Role struct { + KeyIDs []string `json:"keyids"` + Threshold int `json:"threshold"` +} + +func (r *Role) AddKeyIDs(ids []string) bool { + roleIDs := make(map[string]struct{}) + for _, id := range r.KeyIDs { + roleIDs[id] = struct{}{} + } + changed := false + for _, id := range ids { + if _, ok := roleIDs[id]; !ok { + changed = true + r.KeyIDs = append(r.KeyIDs, id) + } + } + return changed +} + +type Files map[string]TargetFileMeta + +type Hashes map[string]HexBytes + +func (f Hashes) HashAlgorithms() []string { + funcs := make([]string, 0, len(f)) + for name := range f { + funcs = append(funcs, name) + } + return funcs +} + +type metapathFileMeta struct { + Length int64 `json:"length,omitempty"` + Hashes Hashes `json:"hashes,omitempty"` + Version int64 `json:"version"` + Custom *json.RawMessage `json:"custom,omitempty"` +} + +// SnapshotFileMeta is the meta field of a snapshot +// Note: Contains a `custom` field +type SnapshotFileMeta metapathFileMeta + +type SnapshotFiles map[string]SnapshotFileMeta + +type Snapshot struct { + Type string `json:"_type"` + SpecVersion string `json:"spec_version"` + Version int64 `json:"version"` + Expires time.Time `json:"expires"` + Meta SnapshotFiles `json:"meta"` + Custom *json.RawMessage `json:"custom,omitempty"` +} + +func NewSnapshot() *Snapshot { + return &Snapshot{ + Type: "snapshot", + SpecVersion: "1.0", + Expires: DefaultExpires("snapshot"), + Meta: make(SnapshotFiles), + } +} + +type FileMeta struct { + Length int64 `json:"length"` + Hashes Hashes `json:"hashes"` +} + +type TargetFiles map[string]TargetFileMeta + +type TargetFileMeta struct { + FileMeta + Custom *json.RawMessage `json:"custom,omitempty"` +} + +func (f TargetFileMeta) HashAlgorithms() []string { + return f.FileMeta.Hashes.HashAlgorithms() +} + +type Targets struct { + Type string `json:"_type"` + SpecVersion string `json:"spec_version"` + Version int64 `json:"version"` + Expires time.Time `json:"expires"` + Targets TargetFiles `json:"targets"` + Delegations *Delegations `json:"delegations,omitempty"` + Custom *json.RawMessage `json:"custom,omitempty"` +} + +// Delegations represents the edges from a parent Targets role to one or more +// delegated target roles. See spec v1.0.19 section 4.5. +type Delegations struct { + Keys map[string]*PublicKey `json:"keys"` + Roles []DelegatedRole `json:"roles"` +} + +// DelegatedRole describes a delegated role, including what paths it is +// reponsible for. See spec v1.0.19 section 4.5. +type DelegatedRole struct { + Name string `json:"name"` + KeyIDs []string `json:"keyids"` + Threshold int `json:"threshold"` + Terminating bool `json:"terminating"` + PathHashPrefixes []string `json:"path_hash_prefixes,omitempty"` + Paths []string `json:"paths"` +} + +// MatchesPath evaluates whether the path patterns or path hash prefixes match +// a given file. This determines whether a delegated role is responsible for +// signing and verifying the file. +func (d *DelegatedRole) MatchesPath(file string) (bool, error) { + if err := d.validatePaths(); err != nil { + return false, err + } + + for _, pattern := range d.Paths { + if matched, _ := path.Match(pattern, file); matched { + return true, nil + } + } + + pathHash := PathHexDigest(file) + for _, hashPrefix := range d.PathHashPrefixes { + if strings.HasPrefix(pathHash, hashPrefix) { + return true, nil + } + } + + return false, nil +} + +// validatePaths enforces the spec +// https://theupdateframework.github.io/specification/v1.0.19/index.html#file-formats-targets +// 'role MUST specify only one of the "path_hash_prefixes" or "paths"' +// Marshalling and unmarshalling JSON will fail and return +// ErrPathsAndPathHashesSet if both fields are set and not empty. +func (d *DelegatedRole) validatePaths() error { + if len(d.PathHashPrefixes) > 0 && len(d.Paths) > 0 { + return ErrPathsAndPathHashesSet + } + + return nil +} + +// MarshalJSON is called when writing the struct to JSON. We validate prior to +// marshalling to ensure that an invalid delegated role can not be serialized +// to JSON. +func (d *DelegatedRole) MarshalJSON() ([]byte, error) { + type delegatedRoleAlias DelegatedRole + + if err := d.validatePaths(); err != nil { + return nil, err + } + + return json.Marshal((*delegatedRoleAlias)(d)) +} + +// UnmarshalJSON is called when reading the struct from JSON. We validate once +// unmarshalled to ensure that an error is thrown if an invalid delegated role +// is read. +func (d *DelegatedRole) UnmarshalJSON(b []byte) error { + type delegatedRoleAlias DelegatedRole + + // Prepare decoder + dec := json.NewDecoder(bytes.NewReader(b)) + + // Unmarshal delegated role + if err := dec.Decode((*delegatedRoleAlias)(d)); err != nil { + return err + } + + return d.validatePaths() +} + +func NewTargets() *Targets { + return &Targets{ + Type: "targets", + SpecVersion: "1.0", + Expires: DefaultExpires("targets"), + Targets: make(TargetFiles), + } +} + +type TimestampFileMeta metapathFileMeta + +type TimestampFiles map[string]TimestampFileMeta + +type Timestamp struct { + Type string `json:"_type"` + SpecVersion string `json:"spec_version"` + Version int64 `json:"version"` + Expires time.Time `json:"expires"` + Meta TimestampFiles `json:"meta"` + Custom *json.RawMessage `json:"custom,omitempty"` +} + +func NewTimestamp() *Timestamp { + return &Timestamp{ + Type: "timestamp", + SpecVersion: "1.0", + Expires: DefaultExpires("timestamp"), + Meta: make(TimestampFiles), + } +} diff --git a/vendor/github.com/DataDog/go-tuf/internal/roles/roles.go b/vendor/github.com/DataDog/go-tuf/internal/roles/roles.go new file mode 100644 index 000000000..0b134b2a0 --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/internal/roles/roles.go @@ -0,0 +1,48 @@ +package roles + +import ( + "strconv" + "strings" +) + +var TopLevelRoles = map[string]struct{}{ + "root": {}, + "targets": {}, + "snapshot": {}, + "timestamp": {}, +} + +func IsTopLevelRole(name string) bool { + _, ok := TopLevelRoles[name] + return ok +} + +func IsDelegatedTargetsRole(name string) bool { + return !IsTopLevelRole(name) +} + +func IsTopLevelManifest(name string) bool { + if IsVersionedManifest(name) { + var found bool + _, name, found = strings.Cut(name, ".") + if !found { + panic("expected a versioned manifest of the form x.role.json") + } + } + return IsTopLevelRole(strings.TrimSuffix(name, ".json")) +} + +func IsDelegatedTargetsManifest(name string) bool { + return !IsTopLevelManifest(name) +} + +func IsVersionedManifest(name string) bool { + parts := strings.Split(name, ".") + // Versioned manifests have the form "x.role.json" + if len(parts) < 3 { + return false + } + + _, err := strconv.Atoi(parts[0]) + return err == nil +} diff --git a/vendor/github.com/DataDog/go-tuf/internal/sets/strings.go b/vendor/github.com/DataDog/go-tuf/internal/sets/strings.go new file mode 100644 index 000000000..7eee57d09 --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/internal/sets/strings.go @@ -0,0 +1,24 @@ +package sets + +func StringSliceToSet(items []string) map[string]struct{} { + s := map[string]struct{}{} + for _, item := range items { + s[item] = struct{}{} + } + return s +} + +func StringSetToSlice(items map[string]struct{}) []string { + ret := []string{} + + for k := range items { + ret = append(ret, k) + } + + return ret +} + +func DeduplicateStrings(items []string) []string { + s := StringSliceToSet(items) + return StringSetToSlice(s) +} diff --git a/vendor/github.com/DataDog/go-tuf/pkg/keys/deprecated_ecdsa.go b/vendor/github.com/DataDog/go-tuf/pkg/keys/deprecated_ecdsa.go new file mode 100644 index 000000000..6c4c20682 --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/pkg/keys/deprecated_ecdsa.go @@ -0,0 +1,101 @@ +package keys + +import ( + "bytes" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/sha256" + "encoding/json" + "errors" + "fmt" + "io" + + "github.com/DataDog/go-tuf/data" +) + +func NewDeprecatedEcdsaVerifier() Verifier { + return &ecdsaVerifierWithDeprecatedSupport{} +} + +type ecdsaVerifierWithDeprecatedSupport struct { + key *data.PublicKey + // This will switch based on whether this is a PEM-encoded key + // or a deprecated hex-encoded key. + Verifier +} + +func (p *ecdsaVerifierWithDeprecatedSupport) UnmarshalPublicKey(key *data.PublicKey) error { + p.key = key + pemVerifier := &EcdsaVerifier{} + if err := pemVerifier.UnmarshalPublicKey(key); err != nil { + // Try the deprecated hex-encoded verifier + hexVerifier := &deprecatedP256Verifier{} + if err := hexVerifier.UnmarshalPublicKey(key); err != nil { + return err + } + p.Verifier = hexVerifier + return nil + } + p.Verifier = pemVerifier + return nil +} + +/* + Deprecated ecdsaVerifier that used hex-encoded public keys. + This MAY be used to verify existing metadata that used this + old format. This will be deprecated soon, ensure that repositories + are re-signed and clients receieve a fully compliant root. +*/ + +type deprecatedP256Verifier struct { + PublicKey data.HexBytes `json:"public"` + key *data.PublicKey +} + +func (p *deprecatedP256Verifier) Public() string { + return p.PublicKey.String() +} + +func (p *deprecatedP256Verifier) Verify(msg, sigBytes []byte) error { + x, y := elliptic.Unmarshal(elliptic.P256(), p.PublicKey) + k := &ecdsa.PublicKey{ + Curve: elliptic.P256(), + X: x, + Y: y, + } + + hash := sha256.Sum256(msg) + + if !ecdsa.VerifyASN1(k, hash[:], sigBytes) { + return errors.New("tuf: deprecated ecdsa signature verification failed") + } + return nil +} + +func (p *deprecatedP256Verifier) MarshalPublicKey() *data.PublicKey { + return p.key +} + +func (p *deprecatedP256Verifier) UnmarshalPublicKey(key *data.PublicKey) error { + // Prepare decoder limited to 512Kb + dec := json.NewDecoder(io.LimitReader(bytes.NewReader(key.Value), MaxJSONKeySize)) + + // Unmarshal key value + if err := dec.Decode(p); err != nil { + if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { + return fmt.Errorf("tuf: the public key is truncated or too large: %w", err) + } + return err + } + + curve := elliptic.P256() + + // Parse as uncompressed marshalled point. + x, _ := elliptic.Unmarshal(curve, p.PublicKey) + if x == nil { + return errors.New("tuf: invalid ecdsa public key point") + } + + p.key = key + return nil +} diff --git a/vendor/github.com/DataDog/go-tuf/pkg/keys/ecdsa.go b/vendor/github.com/DataDog/go-tuf/pkg/keys/ecdsa.go new file mode 100644 index 000000000..ea75b97e8 --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/pkg/keys/ecdsa.go @@ -0,0 +1,173 @@ +package keys + +import ( + "bytes" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/sha256" + "crypto/x509" + "encoding/json" + "encoding/pem" + "errors" + "fmt" + "io" + + "github.com/DataDog/go-tuf/data" +) + +func init() { + // Note: we use LoadOrStore here to prevent accidentally overriding the + // an explicit deprecated ECDSA verifier. + // TODO: When deprecated ECDSA is removed, this can switch back to Store. + VerifierMap.LoadOrStore(data.KeyTypeECDSA_SHA2_P256_OLD_FMT, NewEcdsaVerifier) + VerifierMap.LoadOrStore(data.KeyTypeECDSA_SHA2_P256, NewEcdsaVerifier) + SignerMap.Store(data.KeyTypeECDSA_SHA2_P256_OLD_FMT, newEcdsaSigner) + SignerMap.Store(data.KeyTypeECDSA_SHA2_P256, newEcdsaSigner) +} + +func NewEcdsaVerifier() Verifier { + return &EcdsaVerifier{} +} + +func newEcdsaSigner() Signer { + return &ecdsaSigner{} +} + +type EcdsaVerifier struct { + PublicKey *PKIXPublicKey `json:"public"` + ecdsaKey *ecdsa.PublicKey + key *data.PublicKey +} + +func (p *EcdsaVerifier) Public() string { + // This is already verified to succeed when unmarshalling a public key. + r, err := x509.MarshalPKIXPublicKey(p.ecdsaKey) + if err != nil { + // TODO: Gracefully handle these errors. + // See https://github.com/DataDog/go-tuf/issues/363 + panic(err) + } + return string(r) +} + +func (p *EcdsaVerifier) Verify(msg, sigBytes []byte) error { + hash := sha256.Sum256(msg) + + if !ecdsa.VerifyASN1(p.ecdsaKey, hash[:], sigBytes) { + return errors.New("tuf: ecdsa signature verification failed") + } + return nil +} + +func (p *EcdsaVerifier) MarshalPublicKey() *data.PublicKey { + return p.key +} + +func (p *EcdsaVerifier) UnmarshalPublicKey(key *data.PublicKey) error { + // Prepare decoder limited to 512Kb + dec := json.NewDecoder(io.LimitReader(bytes.NewReader(key.Value), MaxJSONKeySize)) + + // Unmarshal key value + if err := dec.Decode(p); err != nil { + if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { + return fmt.Errorf("tuf: the public key is truncated or too large: %w", err) + } + return err + } + + ecdsaKey, ok := p.PublicKey.PublicKey.(*ecdsa.PublicKey) + if !ok { + return fmt.Errorf("invalid public key") + } + + if _, err := x509.MarshalPKIXPublicKey(ecdsaKey); err != nil { + return fmt.Errorf("marshalling to PKIX key: invalid public key") + } + + p.ecdsaKey = ecdsaKey + p.key = key + return nil +} + +type ecdsaSigner struct { + *ecdsa.PrivateKey +} + +type ecdsaPrivateKeyValue struct { + Private string `json:"private"` + Public *PKIXPublicKey `json:"public"` +} + +func (s *ecdsaSigner) PublicData() *data.PublicKey { + // This uses a trusted public key JSON format with a trusted Public value. + keyValBytes, _ := json.Marshal(EcdsaVerifier{PublicKey: &PKIXPublicKey{PublicKey: s.Public()}}) + return &data.PublicKey{ + Type: data.KeyTypeECDSA_SHA2_P256, + Scheme: data.KeySchemeECDSA_SHA2_P256, + Algorithms: data.HashAlgorithms, + Value: keyValBytes, + } +} + +func (s *ecdsaSigner) SignMessage(message []byte) ([]byte, error) { + hash := sha256.Sum256(message) + return ecdsa.SignASN1(rand.Reader, s.PrivateKey, hash[:]) +} + +func (s *ecdsaSigner) MarshalPrivateKey() (*data.PrivateKey, error) { + priv, err := x509.MarshalECPrivateKey(s.PrivateKey) + if err != nil { + return nil, err + } + pemKey := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: priv}) + val, err := json.Marshal(ecdsaPrivateKeyValue{ + Private: string(pemKey), + Public: &PKIXPublicKey{PublicKey: s.Public()}, + }) + if err != nil { + return nil, err + } + return &data.PrivateKey{ + Type: data.KeyTypeECDSA_SHA2_P256, + Scheme: data.KeySchemeECDSA_SHA2_P256, + Algorithms: data.HashAlgorithms, + Value: val, + }, nil +} + +func (s *ecdsaSigner) UnmarshalPrivateKey(key *data.PrivateKey) error { + val := ecdsaPrivateKeyValue{} + if err := json.Unmarshal(key.Value, &val); err != nil { + return err + } + block, _ := pem.Decode([]byte(val.Private)) + if block == nil { + return errors.New("invalid PEM value") + } + if block.Type != "EC PRIVATE KEY" { + return fmt.Errorf("invalid block type: %s", block.Type) + } + k, err := x509.ParseECPrivateKey(block.Bytes) + if err != nil { + return err + } + if k.Curve != elliptic.P256() { + return errors.New("unsupported ecdsa curve") + } + if _, err := json.Marshal(EcdsaVerifier{ + PublicKey: &PKIXPublicKey{PublicKey: k.Public()}}); err != nil { + return fmt.Errorf("invalid public key: %s", err) + } + + s.PrivateKey = k + return nil +} + +func GenerateEcdsaKey() (*ecdsaSigner, error) { + privkey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return nil, err + } + return &ecdsaSigner{privkey}, nil +} diff --git a/vendor/github.com/DataDog/go-tuf/pkg/keys/ed25519.go b/vendor/github.com/DataDog/go-tuf/pkg/keys/ed25519.go new file mode 100644 index 000000000..4667147fd --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/pkg/keys/ed25519.go @@ -0,0 +1,161 @@ +package keys + +import ( + "bytes" + "crypto" + "crypto/ed25519" + "crypto/rand" + "crypto/subtle" + "encoding/json" + "errors" + "fmt" + "io" + + "github.com/DataDog/go-tuf/data" +) + +func init() { + SignerMap.Store(data.KeyTypeEd25519, NewEd25519Signer) + VerifierMap.Store(data.KeyTypeEd25519, NewEd25519Verifier) +} + +func NewEd25519Signer() Signer { + return &ed25519Signer{} +} + +func NewEd25519Verifier() Verifier { + return &ed25519Verifier{} +} + +type ed25519Verifier struct { + PublicKey data.HexBytes `json:"public"` + key *data.PublicKey +} + +func (e *ed25519Verifier) Public() string { + return string(e.PublicKey) +} + +func (e *ed25519Verifier) Verify(msg, sig []byte) error { + if !ed25519.Verify([]byte(e.PublicKey), msg, sig) { + return errors.New("tuf: ed25519 signature verification failed") + } + return nil +} + +func (e *ed25519Verifier) MarshalPublicKey() *data.PublicKey { + return e.key +} + +func (e *ed25519Verifier) UnmarshalPublicKey(key *data.PublicKey) error { + e.key = key + + // Prepare decoder limited to 512Kb + dec := json.NewDecoder(io.LimitReader(bytes.NewReader(key.Value), MaxJSONKeySize)) + + // Unmarshal key value + if err := dec.Decode(e); err != nil { + if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { + return fmt.Errorf("tuf: the public key is truncated or too large: %w", err) + } + return err + } + if n := len(e.PublicKey); n != ed25519.PublicKeySize { + return fmt.Errorf("tuf: unexpected public key length for ed25519 key, expected %d, got %d", ed25519.PublicKeySize, n) + } + return nil +} + +type Ed25519PrivateKeyValue struct { + Public data.HexBytes `json:"public"` + Private data.HexBytes `json:"private"` +} + +type ed25519Signer struct { + ed25519.PrivateKey +} + +func GenerateEd25519Key() (*ed25519Signer, error) { + _, private, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + return nil, err + } + if err != nil { + return nil, err + } + return &ed25519Signer{ + PrivateKey: ed25519.PrivateKey(data.HexBytes(private)), + }, nil +} + +func NewEd25519SignerFromKey(keyValue Ed25519PrivateKeyValue) *ed25519Signer { + return &ed25519Signer{ + PrivateKey: ed25519.PrivateKey(data.HexBytes(keyValue.Private)), + } +} + +func (e *ed25519Signer) SignMessage(message []byte) ([]byte, error) { + return e.Sign(rand.Reader, message, crypto.Hash(0)) +} + +func (e *ed25519Signer) MarshalPrivateKey() (*data.PrivateKey, error) { + valueBytes, err := json.Marshal(Ed25519PrivateKeyValue{ + Public: data.HexBytes([]byte(e.PrivateKey.Public().(ed25519.PublicKey))), + Private: data.HexBytes(e.PrivateKey), + }) + if err != nil { + return nil, err + } + return &data.PrivateKey{ + Type: data.KeyTypeEd25519, + Scheme: data.KeySchemeEd25519, + Algorithms: data.HashAlgorithms, + Value: valueBytes, + }, nil +} + +func (e *ed25519Signer) UnmarshalPrivateKey(key *data.PrivateKey) error { + keyValue := &Ed25519PrivateKeyValue{} + + // Prepare decoder limited to 512Kb + dec := json.NewDecoder(io.LimitReader(bytes.NewReader(key.Value), MaxJSONKeySize)) + + // Unmarshal key value + if err := dec.Decode(keyValue); err != nil { + if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { + return fmt.Errorf("tuf: the private key is truncated or too large: %w", err) + } + } + + // Check private key length + if n := len(keyValue.Private); n != ed25519.PrivateKeySize { + return fmt.Errorf("tuf: invalid ed25519 private key length, expected %d, got %d", ed25519.PrivateKeySize, n) + } + + // Generate public key from private key + pub, _, err := ed25519.GenerateKey(bytes.NewReader(keyValue.Private)) + if err != nil { + return fmt.Errorf("tuf: unable to derive public key from private key: %w", err) + } + + // Compare keys + if subtle.ConstantTimeCompare(keyValue.Public, pub) != 1 { + return errors.New("tuf: public and private keys don't match") + } + + // Prepare signer + *e = ed25519Signer{ + PrivateKey: ed25519.PrivateKey(data.HexBytes(keyValue.Private)), + } + return nil +} + +func (e *ed25519Signer) PublicData() *data.PublicKey { + keyValBytes, _ := json.Marshal(ed25519Verifier{PublicKey: []byte(e.PrivateKey.Public().(ed25519.PublicKey))}) + return &data.PublicKey{ + Type: data.KeyTypeEd25519, + Scheme: data.KeySchemeEd25519, + Algorithms: data.HashAlgorithms, + Value: keyValBytes, + } +} diff --git a/vendor/github.com/DataDog/go-tuf/pkg/keys/keys.go b/vendor/github.com/DataDog/go-tuf/pkg/keys/keys.go new file mode 100644 index 000000000..7fc25316e --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/pkg/keys/keys.go @@ -0,0 +1,82 @@ +package keys + +import ( + "errors" + "fmt" + "sync" + + "github.com/DataDog/go-tuf/data" +) + +// MaxJSONKeySize defines the maximum length of a JSON payload. +const MaxJSONKeySize = 512 * 1024 // 512Kb + +// SignerMap stores mapping between key type strings and signer constructors. +var SignerMap sync.Map + +// Verifier stores mapping between key type strings and verifier constructors. +var VerifierMap sync.Map + +var ( + ErrInvalid = errors.New("tuf: signature verification failed") + ErrInvalidKey = errors.New("invalid key") +) + +// A Verifier verifies public key signatures. +type Verifier interface { + // UnmarshalPublicKey takes key data to a working verifier implementation for the key type. + // This performs any validation over the data.PublicKey to ensure that the verifier is usable + // to verify signatures. + UnmarshalPublicKey(key *data.PublicKey) error + + // MarshalPublicKey returns the data.PublicKey object associated with the verifier. + MarshalPublicKey() *data.PublicKey + + // This is the public string used as a unique identifier for the verifier instance. + Public() string + + // Verify takes a message and signature, all as byte slices, + // and determines whether the signature is valid for the given + // key and message. + Verify(msg, sig []byte) error +} + +type Signer interface { + // MarshalPrivateKey returns the private key data. + MarshalPrivateKey() (*data.PrivateKey, error) + + // UnmarshalPrivateKey takes private key data to a working Signer implementation for the key type. + UnmarshalPrivateKey(key *data.PrivateKey) error + + // Returns the public data.PublicKey from the private key + PublicData() *data.PublicKey + + // Sign returns the signature of the message. + // The signer is expected to do its own hashing, so the full message will be + // provided as the message to Sign with a zero opts.HashFunc(). + SignMessage(message []byte) ([]byte, error) +} + +func GetVerifier(key *data.PublicKey) (Verifier, error) { + st, ok := VerifierMap.Load(key.Type) + if !ok { + return nil, ErrInvalidKey + } + s := st.(func() Verifier)() + if err := s.UnmarshalPublicKey(key); err != nil { + return nil, fmt.Errorf("tuf: error unmarshalling key: %w", err) + } + return s, nil +} + +func GetSigner(key *data.PrivateKey) (Signer, error) { + st, ok := SignerMap.Load(key.Type) + if !ok { + return nil, ErrInvalidKey + } + s := st.(func() Signer)() + if err := s.UnmarshalPrivateKey(key); err != nil { + return nil, fmt.Errorf("tuf: error unmarshalling key: %w", err) + } + return s, nil +} diff --git a/vendor/github.com/DataDog/go-tuf/pkg/keys/pkix.go b/vendor/github.com/DataDog/go-tuf/pkg/keys/pkix.go new file mode 100644 index 000000000..e58d4c9f8 --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/pkg/keys/pkix.go @@ -0,0 +1,56 @@ +package keys + +import ( + "bytes" + "crypto" + "crypto/x509" + "encoding/json" + "encoding/pem" + "errors" + "fmt" + "io" +) + +type PKIXPublicKey struct { + crypto.PublicKey +} + +func (p *PKIXPublicKey) MarshalJSON() ([]byte, error) { + bytes, err := x509.MarshalPKIXPublicKey(p.PublicKey) + if err != nil { + return nil, err + } + pemBytes := pem.EncodeToMemory(&pem.Block{ + Type: "PUBLIC KEY", + Bytes: bytes, + }) + return json.Marshal(string(pemBytes)) +} + +func (p *PKIXPublicKey) UnmarshalJSON(b []byte) error { + var pemValue string + // Prepare decoder limited to 512Kb + dec := json.NewDecoder(io.LimitReader(bytes.NewReader(b), MaxJSONKeySize)) + + // Unmarshal key value + if err := dec.Decode(&pemValue); err != nil { + if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { + return fmt.Errorf("tuf: the public key is truncated or too large: %w", err) + } + return err + } + + block, _ := pem.Decode([]byte(pemValue)) + if block == nil { + return errors.New("invalid PEM value") + } + if block.Type != "PUBLIC KEY" { + return fmt.Errorf("invalid block type: %s", block.Type) + } + pub, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return err + } + p.PublicKey = pub + return nil +} diff --git a/vendor/github.com/DataDog/go-tuf/pkg/keys/rsa.go b/vendor/github.com/DataDog/go-tuf/pkg/keys/rsa.go new file mode 100644 index 000000000..17d7690a7 --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/pkg/keys/rsa.go @@ -0,0 +1,162 @@ +package keys + +import ( + "bytes" + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "crypto/x509" + "encoding/json" + "encoding/pem" + "errors" + "fmt" + "io" + + "github.com/DataDog/go-tuf/data" +) + +func init() { + VerifierMap.Store(data.KeyTypeRSASSA_PSS_SHA256, newRsaVerifier) + SignerMap.Store(data.KeyTypeRSASSA_PSS_SHA256, newRsaSigner) +} + +func newRsaVerifier() Verifier { + return &rsaVerifier{} +} + +func newRsaSigner() Signer { + return &rsaSigner{} +} + +type rsaVerifier struct { + PublicKey *PKIXPublicKey `json:"public"` + rsaKey *rsa.PublicKey + key *data.PublicKey +} + +func (p *rsaVerifier) Public() string { + // This is already verified to succeed when unmarshalling a public key. + r, err := x509.MarshalPKIXPublicKey(p.rsaKey) + if err != nil { + // TODO: Gracefully handle these errors. + // See https://github.com/DataDog/go-tuf/issues/363 + panic(err) + } + return string(r) +} + +func (p *rsaVerifier) Verify(msg, sigBytes []byte) error { + hash := sha256.Sum256(msg) + + return rsa.VerifyPSS(p.rsaKey, crypto.SHA256, hash[:], sigBytes, &rsa.PSSOptions{}) +} + +func (p *rsaVerifier) MarshalPublicKey() *data.PublicKey { + return p.key +} + +func (p *rsaVerifier) UnmarshalPublicKey(key *data.PublicKey) error { + // Prepare decoder limited to 512Kb + dec := json.NewDecoder(io.LimitReader(bytes.NewReader(key.Value), MaxJSONKeySize)) + + // Unmarshal key value + if err := dec.Decode(p); err != nil { + if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { + return fmt.Errorf("tuf: the public key is truncated or too large: %w", err) + } + return err + } + + rsaKey, ok := p.PublicKey.PublicKey.(*rsa.PublicKey) + if !ok { + return fmt.Errorf("invalid public key") + } + + if _, err := x509.MarshalPKIXPublicKey(rsaKey); err != nil { + return fmt.Errorf("marshalling to PKIX key: invalid public key") + } + + p.rsaKey = rsaKey + p.key = key + return nil +} + +type rsaSigner struct { + *rsa.PrivateKey +} + +type rsaPrivateKeyValue struct { + Private string `json:"private"` + Public *PKIXPublicKey `json:"public"` +} + +func (s *rsaSigner) PublicData() *data.PublicKey { + keyValBytes, _ := json.Marshal(rsaVerifier{PublicKey: &PKIXPublicKey{PublicKey: s.Public()}}) + return &data.PublicKey{ + Type: data.KeyTypeRSASSA_PSS_SHA256, + Scheme: data.KeySchemeRSASSA_PSS_SHA256, + Algorithms: data.HashAlgorithms, + Value: keyValBytes, + } +} + +func (s *rsaSigner) SignMessage(message []byte) ([]byte, error) { + hash := sha256.Sum256(message) + return rsa.SignPSS(rand.Reader, s.PrivateKey, crypto.SHA256, hash[:], &rsa.PSSOptions{}) +} + +func (s *rsaSigner) ContainsID(id string) bool { + return s.PublicData().ContainsID(id) +} + +func (s *rsaSigner) MarshalPrivateKey() (*data.PrivateKey, error) { + priv := x509.MarshalPKCS1PrivateKey(s.PrivateKey) + pemKey := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: priv}) + val, err := json.Marshal(rsaPrivateKeyValue{ + Private: string(pemKey), + Public: &PKIXPublicKey{PublicKey: s.Public()}, + }) + if err != nil { + return nil, err + } + return &data.PrivateKey{ + Type: data.KeyTypeRSASSA_PSS_SHA256, + Scheme: data.KeySchemeRSASSA_PSS_SHA256, + Algorithms: data.HashAlgorithms, + Value: val, + }, nil +} + +func (s *rsaSigner) UnmarshalPrivateKey(key *data.PrivateKey) error { + val := rsaPrivateKeyValue{} + if err := json.Unmarshal(key.Value, &val); err != nil { + return err + } + block, _ := pem.Decode([]byte(val.Private)) + if block == nil { + return errors.New("invalid PEM value") + } + if block.Type != "RSA PRIVATE KEY" { + return fmt.Errorf("invalid block type: %s", block.Type) + } + k, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return err + } + if _, err := json.Marshal(rsaVerifier{ + PublicKey: &PKIXPublicKey{PublicKey: k.Public()}}); err != nil { + return fmt.Errorf("invalid public key: %s", err) + } + + s.PrivateKey = k + return nil +} + +func GenerateRsaKey() (*rsaSigner, error) { + privkey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return nil, err + } + return &rsaSigner{privkey}, nil +} diff --git a/vendor/github.com/DataDog/go-tuf/pkg/targets/delegation.go b/vendor/github.com/DataDog/go-tuf/pkg/targets/delegation.go new file mode 100644 index 000000000..d155d070f --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/pkg/targets/delegation.go @@ -0,0 +1,102 @@ +package targets + +import ( + "errors" + + "github.com/DataDog/go-tuf/data" + "github.com/DataDog/go-tuf/internal/sets" + "github.com/DataDog/go-tuf/verify" +) + +type Delegation struct { + Delegator string + Delegatee data.DelegatedRole + DB *verify.DB +} + +type delegationsIterator struct { + stack []Delegation + target string + visitedRoles map[string]struct{} + parents map[string]string +} + +var ErrTopLevelTargetsRoleMissing = errors.New("tuf: top level targets role missing from top level keys DB") + +// NewDelegationsIterator initialises an iterator with a first step +// on top level targets. +func NewDelegationsIterator(target string, topLevelKeysDB *verify.DB) (*delegationsIterator, error) { + targetsRole := topLevelKeysDB.GetRole("targets") + if targetsRole == nil { + return nil, ErrTopLevelTargetsRoleMissing + } + + i := &delegationsIterator{ + target: target, + stack: []Delegation{ + { + Delegatee: data.DelegatedRole{ + Name: "targets", + KeyIDs: sets.StringSetToSlice(targetsRole.KeyIDs), + Threshold: targetsRole.Threshold, + }, + DB: topLevelKeysDB, + }, + }, + visitedRoles: make(map[string]struct{}), + parents: make(map[string]string), + } + return i, nil +} + +func (d *delegationsIterator) Next() (value Delegation, ok bool) { + if len(d.stack) == 0 { + return Delegation{}, false + } + delegation := d.stack[len(d.stack)-1] + d.stack = d.stack[:len(d.stack)-1] + + // 5.6.7.1: If this role has been visited before, then skip this role (so + // that cycles in the delegation graph are avoided). + roleName := delegation.Delegatee.Name + if _, ok := d.visitedRoles[roleName]; ok { + return d.Next() + } + d.visitedRoles[roleName] = struct{}{} + + // 5.6.7.2 trim delegations to visit, only the current role and its delegations + // will be considered + // https://github.com/theupdateframework/specification/issues/168 + if delegation.Delegatee.Terminating { + // Empty the stack. + d.stack = d.stack[0:0] + } + return delegation, true +} + +func (d *delegationsIterator) Add(roles []data.DelegatedRole, delegator string, db *verify.DB) error { + for i := len(roles) - 1; i >= 0; i-- { + // Push the roles onto the stack in reverse so we get an preorder traversal + // of the delegations graph. + r := roles[i] + matchesPath, err := r.MatchesPath(d.target) + if err != nil { + return err + } + if matchesPath { + delegation := Delegation{ + Delegator: delegator, + Delegatee: r, + DB: db, + } + d.stack = append(d.stack, delegation) + d.parents[r.Name] = delegator + } + } + + return nil +} + +func (d *delegationsIterator) Parent(role string) string { + return d.parents[role] +} diff --git a/vendor/github.com/DataDog/go-tuf/pkg/targets/hash_bins.go b/vendor/github.com/DataDog/go-tuf/pkg/targets/hash_bins.go new file mode 100644 index 000000000..95f4405d4 --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/pkg/targets/hash_bins.go @@ -0,0 +1,113 @@ +package targets + +import ( + "fmt" + "strconv" + "strings" +) + +const MinDelegationHashPrefixBitLen = 1 +const MaxDelegationHashPrefixBitLen = 32 + +// hexEncode formats x as a hex string. The hex string is left padded with +// zeros to padWidth, if necessary. +func hexEncode(x uint64, padWidth int) string { + // Benchmarked to be more than 10x faster than padding with Sprintf. + s := strconv.FormatUint(x, 16) + if len(s) >= padWidth { + return s + } + return strings.Repeat("0", padWidth-len(s)) + s +} + +const bitsPerHexDigit = 4 + +// numHexDigits returns the number of hex digits required to encode the given +// number of bits. +func numHexDigits(numBits int) int { + // ceil(numBits / bitsPerHexDigit) + return ((numBits - 1) / bitsPerHexDigit) + 1 +} + +// HashBins represents an ordered list of hash bin target roles, which together +// partition the space of target path hashes equal-sized buckets based on path +// has prefix. +type HashBins struct { + rolePrefix string + bitLen int + hexDigitLen int + + numBins uint64 + numPrefixesPerBin uint64 +} + +// NewHashBins creates a HashBins partitioning with 2^bitLen buckets. +func NewHashBins(rolePrefix string, bitLen int) (*HashBins, error) { + if bitLen < MinDelegationHashPrefixBitLen || bitLen > MaxDelegationHashPrefixBitLen { + return nil, fmt.Errorf("bitLen is out of bounds, should be between %v and %v inclusive", MinDelegationHashPrefixBitLen, MaxDelegationHashPrefixBitLen) + } + + hexDigitLen := numHexDigits(bitLen) + numBins := uint64(1) << bitLen + + numPrefixesTotal := uint64(1) << (bitsPerHexDigit * hexDigitLen) + numPrefixesPerBin := numPrefixesTotal / numBins + + return &HashBins{ + rolePrefix: rolePrefix, + bitLen: bitLen, + hexDigitLen: hexDigitLen, + numBins: numBins, + numPrefixesPerBin: numPrefixesPerBin, + }, nil +} + +// NumBins returns the number of hash bin partitions. +func (hb *HashBins) NumBins() uint64 { + return hb.numBins +} + +// GetBin returns the HashBin at index i, or nil if i is out of bounds. +func (hb *HashBins) GetBin(i uint64) *HashBin { + if i >= hb.numBins { + return nil + } + + return &HashBin{ + rolePrefix: hb.rolePrefix, + hexDigitLen: hb.hexDigitLen, + first: i * hb.numPrefixesPerBin, + last: ((i + 1) * hb.numPrefixesPerBin) - 1, + } +} + +// HashBin represents a hex prefix range. First should be less than Last. +type HashBin struct { + rolePrefix string + hexDigitLen int + first uint64 + last uint64 +} + +// RoleName returns the name of the role that signs for the HashBin. +func (b *HashBin) RoleName() string { + if b.first == b.last { + return b.rolePrefix + hexEncode(b.first, b.hexDigitLen) + } + + return b.rolePrefix + hexEncode(b.first, b.hexDigitLen) + "-" + hexEncode(b.last, b.hexDigitLen) +} + +// HashPrefixes returns a slice of all hash prefixes in the bin. +func (b *HashBin) HashPrefixes() []string { + n := int(b.last - b.first + 1) + ret := make([]string, int(n)) + + x := b.first + for i := 0; i < n; i++ { + ret[i] = hexEncode(x, b.hexDigitLen) + x++ + } + + return ret +} diff --git a/vendor/github.com/DataDog/go-tuf/util/util.go b/vendor/github.com/DataDog/go-tuf/util/util.go new file mode 100644 index 000000000..a9b23b007 --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/util/util.go @@ -0,0 +1,332 @@ +package util + +import ( + "bytes" + "crypto/hmac" + "crypto/sha256" + "crypto/sha512" + "encoding/hex" + "encoding/json" + "fmt" + "hash" + "io" + "os" + "path" + "path/filepath" + "strconv" + "strings" + + "github.com/DataDog/go-tuf/data" +) + +type ErrWrongLength struct { + Expected int64 + Actual int64 +} + +func (e ErrWrongLength) Error() string { + return fmt.Sprintf("wrong length, expected %d got %d", e.Expected, e.Actual) +} + +type ErrWrongVersion struct { + Expected int64 + Actual int64 +} + +func (e ErrWrongVersion) Error() string { + return fmt.Sprintf("wrong version, expected %d got %d", e.Expected, e.Actual) +} + +type ErrWrongHash struct { + Type string + Expected data.HexBytes + Actual data.HexBytes +} + +func (e ErrWrongHash) Error() string { + return fmt.Sprintf("wrong %s hash, expected %s got %s", e.Type, hex.EncodeToString(e.Expected), hex.EncodeToString(e.Actual)) +} + +type ErrNoCommonHash struct { + Expected data.Hashes + Actual data.Hashes +} + +func (e ErrNoCommonHash) Error() string { + types := func(a data.Hashes) []string { + t := make([]string, 0, len(a)) + for typ := range a { + t = append(t, typ) + } + return t + } + return fmt.Sprintf("no common hash function, expected one of %s, got %s", types(e.Expected), types(e.Actual)) +} + +type ErrUnknownHashAlgorithm struct { + Name string +} + +func (e ErrUnknownHashAlgorithm) Error() string { + return fmt.Sprintf("unknown hash algorithm: %s", e.Name) +} + +type PassphraseFunc func(role string, confirm bool, change bool) ([]byte, error) + +func FileMetaEqual(actual data.FileMeta, expected data.FileMeta) error { + if actual.Length != expected.Length { + return ErrWrongLength{expected.Length, actual.Length} + } + + if err := hashEqual(actual.Hashes, expected.Hashes); err != nil { + return err + } + + return nil +} + +func BytesMatchLenAndHashes(fetched []byte, length int64, hashes data.Hashes) error { + flen := int64(len(fetched)) + if length != 0 && flen != length { + return ErrWrongLength{length, flen} + } + + for alg, expected := range hashes { + var h hash.Hash + switch alg { + case "sha256": + h = sha256.New() + case "sha512": + h = sha512.New() + default: + return ErrUnknownHashAlgorithm{alg} + } + h.Write(fetched) + hash := h.Sum(nil) + if !hmac.Equal(hash, expected) { + return ErrWrongHash{alg, expected, hash} + } + } + + return nil +} + +func hashEqual(actual data.Hashes, expected data.Hashes) error { + hashChecked := false + for typ, hash := range expected { + if h, ok := actual[typ]; ok { + hashChecked = true + if !hmac.Equal(h, hash) { + return ErrWrongHash{typ, hash, h} + } + } + } + if !hashChecked { + return ErrNoCommonHash{expected, actual} + } + return nil +} + +func VersionEqual(actual int64, expected int64) error { + if actual != expected { + return ErrWrongVersion{expected, actual} + } + return nil +} + +func SnapshotFileMetaEqual(actual data.SnapshotFileMeta, expected data.SnapshotFileMeta) error { + // TUF-1.0 no longer considers the length and hashes to be a required + // member of snapshots. However they are considering requiring hashes + // for delegated roles to avoid an attack described in Section 5.6 of + // the Mercury paper: + // https://github.com/theupdateframework/specification/pull/40 + if expected.Length != 0 && actual.Length != expected.Length { + return ErrWrongLength{expected.Length, actual.Length} + } + // 5.6.2 - Check against snapshot role's targets hash + if len(expected.Hashes) != 0 { + if err := hashEqual(actual.Hashes, expected.Hashes); err != nil { + return err + } + } + // 5.6.4 - Check against snapshot role's snapshot version + if err := VersionEqual(actual.Version, expected.Version); err != nil { + return err + } + + return nil +} + +func TargetFileMetaEqual(actual data.TargetFileMeta, expected data.TargetFileMeta) error { + return FileMetaEqual(actual.FileMeta, expected.FileMeta) +} + +func TimestampFileMetaEqual(actual data.TimestampFileMeta, expected data.TimestampFileMeta) error { + // TUF no longer considers the length and hashes to be a required + // member of Timestamp. + if expected.Length != 0 && actual.Length != expected.Length { + return ErrWrongLength{expected.Length, actual.Length} + } + // 5.5.2 - Check against timestamp role's snapshot hash + if len(expected.Hashes) != 0 { + if err := hashEqual(actual.Hashes, expected.Hashes); err != nil { + return err + } + } + // 5.5.4 - Check against timestamp role's snapshot version + if err := VersionEqual(actual.Version, expected.Version); err != nil { + return err + } + + return nil +} + +const defaultHashAlgorithm = "sha512" + +func GenerateFileMeta(r io.Reader, hashAlgorithms ...string) (data.FileMeta, error) { + if len(hashAlgorithms) == 0 { + hashAlgorithms = []string{defaultHashAlgorithm} + } + hashes := make(map[string]hash.Hash, len(hashAlgorithms)) + for _, hashAlgorithm := range hashAlgorithms { + var h hash.Hash + switch hashAlgorithm { + case "sha256": + h = sha256.New() + case "sha512": + h = sha512.New() + default: + return data.FileMeta{}, ErrUnknownHashAlgorithm{hashAlgorithm} + } + hashes[hashAlgorithm] = h + r = io.TeeReader(r, h) + } + n, err := io.Copy(io.Discard, r) + if err != nil { + return data.FileMeta{}, err + } + m := data.FileMeta{Length: n, Hashes: make(data.Hashes, len(hashes))} + for hashAlgorithm, h := range hashes { + m.Hashes[hashAlgorithm] = h.Sum(nil) + } + return m, nil +} + +type versionedMeta struct { + Version int64 `json:"version"` +} + +func generateVersionedFileMeta(r io.Reader, hashAlgorithms ...string) (data.FileMeta, int64, error) { + b, err := io.ReadAll(r) + if err != nil { + return data.FileMeta{}, 0, err + } + + m, err := GenerateFileMeta(bytes.NewReader(b), hashAlgorithms...) + if err != nil { + return data.FileMeta{}, 0, err + } + + s := data.Signed{} + if err := json.Unmarshal(b, &s); err != nil { + return data.FileMeta{}, 0, err + } + + vm := versionedMeta{} + if err := json.Unmarshal(s.Signed, &vm); err != nil { + return data.FileMeta{}, 0, err + } + + return m, vm.Version, nil +} + +func GenerateSnapshotFileMeta(r io.Reader, hashAlgorithms ...string) (data.SnapshotFileMeta, error) { + m, v, err := generateVersionedFileMeta(r, hashAlgorithms...) + if err != nil { + return data.SnapshotFileMeta{}, err + } + return data.SnapshotFileMeta{ + Length: m.Length, + Hashes: m.Hashes, + Version: v, + }, nil +} + +func GenerateTargetFileMeta(r io.Reader, hashAlgorithms ...string) (data.TargetFileMeta, error) { + m, err := GenerateFileMeta(r, hashAlgorithms...) + if err != nil { + return data.TargetFileMeta{}, err + } + return data.TargetFileMeta{ + FileMeta: m, + }, nil +} + +func GenerateTimestampFileMeta(r io.Reader, hashAlgorithms ...string) (data.TimestampFileMeta, error) { + m, v, err := generateVersionedFileMeta(r, hashAlgorithms...) + if err != nil { + return data.TimestampFileMeta{}, err + } + return data.TimestampFileMeta{ + Length: m.Length, + Hashes: m.Hashes, + Version: v, + }, nil +} + +func NormalizeTarget(p string) string { + // FIXME(TUF-0.9) TUF-1.0 is considering banning paths that begin with + // a leading path separator, to avoid surprising behavior when joining + // target and delgated paths. python-tuf raises an exception if any + // path starts with '/', but since we need to be cross compatible with + // TUF-0.9 we still need to support leading slashes. For now, we will + // just strip them out, but eventually we should also consider turning + // them into an error. + return strings.TrimPrefix(path.Join("/", p), "/") +} + +func VersionedPath(p string, version int64) string { + return path.Join(path.Dir(p), strconv.FormatInt(version, 10)+"."+path.Base(p)) +} + +func HashedPaths(p string, hashes data.Hashes) []string { + paths := make([]string, 0, len(hashes)) + for _, hash := range hashes { + hashedPath := path.Join(path.Dir(p), hash.String()+"."+path.Base(p)) + paths = append(paths, hashedPath) + } + return paths +} + +func AtomicallyWriteFile(filename string, data []byte, perm os.FileMode) error { + dir, name := filepath.Split(filename) + f, err := os.CreateTemp(dir, name) + if err != nil { + return err + } + + _, err = f.Write(data) + if err != nil { + f.Close() + os.Remove(f.Name()) + return err + } + + if err = f.Chmod(perm); err != nil { + f.Close() + os.Remove(f.Name()) + return err + } + + if err := f.Close(); err != nil { + os.Remove(f.Name()) + return err + } + + if err := os.Rename(f.Name(), filename); err != nil { + os.Remove(f.Name()) + return err + } + + return nil +} diff --git a/vendor/github.com/DataDog/go-tuf/verify/db.go b/vendor/github.com/DataDog/go-tuf/verify/db.go new file mode 100644 index 000000000..1961c98fb --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/verify/db.go @@ -0,0 +1,104 @@ +package verify + +import ( + "github.com/DataDog/go-tuf/data" + "github.com/DataDog/go-tuf/internal/roles" + "github.com/DataDog/go-tuf/pkg/keys" +) + +type Role struct { + KeyIDs map[string]struct{} + Threshold int +} + +func (r *Role) ValidKey(id string) bool { + _, ok := r.KeyIDs[id] + return ok +} + +type DB struct { + roles map[string]*Role + verifiers map[string]keys.Verifier +} + +func NewDB() *DB { + return &DB{ + roles: make(map[string]*Role), + verifiers: make(map[string]keys.Verifier), + } +} + +// NewDBFromDelegations returns a DB that verifies delegations +// of a given Targets. +func NewDBFromDelegations(d *data.Delegations) (*DB, error) { + db := &DB{ + roles: make(map[string]*Role, len(d.Roles)), + verifiers: make(map[string]keys.Verifier, len(d.Keys)), + } + for _, r := range d.Roles { + if _, ok := roles.TopLevelRoles[r.Name]; ok { + return nil, ErrInvalidDelegatedRole + } + role := &data.Role{Threshold: r.Threshold, KeyIDs: r.KeyIDs} + if err := db.AddRole(r.Name, role); err != nil { + return nil, err + } + } + for id, k := range d.Keys { + if err := db.AddKey(id, k); err != nil { + return nil, err + } + } + return db, nil +} + +func (db *DB) AddKey(id string, k *data.PublicKey) error { + verifier, err := keys.GetVerifier(k) + if err != nil { + return err // ErrInvalidKey + } + + // TUF is considering in TAP-12 removing the + // requirement that the keyid hash algorithm be derived + // from the public key. So to be forwards compatible, + // we allow any key ID, rather than checking k.ContainsID(id) + // + // AddKey should be idempotent, so we allow re-adding the same PublicKey. + // + // TAP-12: https://github.com/theupdateframework/taps/blob/master/tap12.md + if oldVerifier, exists := db.verifiers[id]; exists && oldVerifier.Public() != verifier.Public() { + return ErrRepeatID{id} + } + + db.verifiers[id] = verifier + return nil +} + +func (db *DB) AddRole(name string, r *data.Role) error { + if r.Threshold < 1 { + return ErrInvalidThreshold + } + + role := &Role{ + KeyIDs: make(map[string]struct{}), + Threshold: r.Threshold, + } + for _, id := range r.KeyIDs { + role.KeyIDs[id] = struct{}{} + } + + db.roles[name] = role + return nil +} + +func (db *DB) GetVerifier(id string) (keys.Verifier, error) { + k, ok := db.verifiers[id] + if !ok { + return nil, ErrMissingKey + } + return k, nil +} + +func (db *DB) GetRole(name string) *Role { + return db.roles[name] +} diff --git a/vendor/github.com/DataDog/go-tuf/verify/errors.go b/vendor/github.com/DataDog/go-tuf/verify/errors.go new file mode 100644 index 000000000..f71d4bda9 --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/verify/errors.go @@ -0,0 +1,73 @@ +package verify + +import ( + "errors" + "fmt" + "time" +) + +var ( + ErrMissingKey = errors.New("tuf: missing key") + ErrNoSignatures = errors.New("tuf: data has no signatures") + ErrInvalid = errors.New("tuf: signature verification failed") + ErrWrongMethod = errors.New("tuf: invalid signature type") + ErrWrongMetaType = errors.New("tuf: meta file has wrong type") + ErrExists = errors.New("tuf: key already in db") + ErrInvalidKey = errors.New("tuf: invalid key") + ErrInvalidRole = errors.New("tuf: invalid role") + ErrInvalidDelegatedRole = errors.New("tuf: invalid delegated role") + ErrInvalidKeyID = errors.New("tuf: invalid key id") + ErrInvalidThreshold = errors.New("tuf: invalid role threshold") + ErrMissingTargetFile = errors.New("tuf: missing previously listed targets metadata file") +) + +type ErrRepeatID struct { + KeyID string +} + +func (e ErrRepeatID) Error() string { + return fmt.Sprintf("tuf: duplicate key id (%s)", e.KeyID) +} + +type ErrUnknownRole struct { + Role string +} + +func (e ErrUnknownRole) Error() string { + return fmt.Sprintf("tuf: unknown role %q", e.Role) +} + +type ErrExpired struct { + Expired time.Time +} + +func (e ErrExpired) Error() string { + return fmt.Sprintf("expired at %s", e.Expired) +} + +type ErrLowVersion struct { + Actual int64 + Current int64 +} + +func (e ErrLowVersion) Error() string { + return fmt.Sprintf("version %d is lower than current version %d", e.Actual, e.Current) +} + +type ErrWrongVersion struct { + Given int64 + Expected int64 +} + +func (e ErrWrongVersion) Error() string { + return fmt.Sprintf("version %d does not match the expected version %d", e.Given, e.Expected) +} + +type ErrRoleThreshold struct { + Expected int + Actual int +} + +func (e ErrRoleThreshold) Error() string { + return "tuf: valid signatures did not meet threshold" +} diff --git a/vendor/github.com/DataDog/go-tuf/verify/verify.go b/vendor/github.com/DataDog/go-tuf/verify/verify.go new file mode 100644 index 000000000..b0cf333ca --- /dev/null +++ b/vendor/github.com/DataDog/go-tuf/verify/verify.go @@ -0,0 +1,187 @@ +package verify + +import ( + "encoding/json" + "strings" + "time" + + "github.com/DataDog/go-tuf/data" + "github.com/DataDog/go-tuf/internal/roles" + "github.com/DataDog/go-tuf/pkg/keys" + "github.com/secure-systems-lab/go-securesystemslib/cjson" +) + +type signedMeta struct { + Type string `json:"_type"` + Expires time.Time `json:"expires"` + Version int64 `json:"version"` +} + +// VerifySignature takes a signed JSON message, a signature, and a +// verifier and verifies the given signature on the JSON message +// using the verifier. It returns an error if verification fails. +func VerifySignature(signed json.RawMessage, sig data.HexBytes, + verifier keys.Verifier) error { + var decoded map[string]interface{} + if err := json.Unmarshal(signed, &decoded); err != nil { + return err + } + msg, err := cjson.EncodeCanonical(decoded) + if err != nil { + return err + } + return verifier.Verify(msg, sig) +} + +func (db *DB) VerifyIgnoreExpiredCheck(s *data.Signed, role string, minVersion int64) error { + if err := db.VerifySignatures(s, role); err != nil { + return err + } + + sm := &signedMeta{} + if err := json.Unmarshal(s.Signed, sm); err != nil { + return err + } + + if roles.IsTopLevelRole(role) { + // Top-level roles can only sign metadata of the same type (e.g. snapshot + // metadata must be signed by the snapshot role). + if !strings.EqualFold(sm.Type, role) { + return ErrWrongMetaType + } + } else { + // Delegated (non-top-level) roles may only sign targets metadata. + if strings.ToLower(sm.Type) != "targets" { + return ErrWrongMetaType + } + } + + if sm.Version < minVersion { + return ErrLowVersion{sm.Version, minVersion} + } + + return nil +} + +func (db *DB) Verify(s *data.Signed, role string, minVersion int64) error { + // Verify signatures and versions + err := db.VerifyIgnoreExpiredCheck(s, role, minVersion) + + if err != nil { + return err + } + + sm := &signedMeta{} + if err := json.Unmarshal(s.Signed, sm); err != nil { + return err + } + // Verify expiration + if IsExpired(sm.Expires) { + return ErrExpired{sm.Expires} + } + + return nil +} + +var IsExpired = func(t time.Time) bool { + return time.Until(t) <= 0 +} + +func (db *DB) VerifySignatures(s *data.Signed, role string) error { + if len(s.Signatures) == 0 { + return ErrNoSignatures + } + + roleData := db.GetRole(role) + if roleData == nil { + return ErrUnknownRole{role} + } + + // Verify that a threshold of keys signed the data. Since keys can have + // multiple key ids, we need to protect against multiple attached + // signatures that just differ on the key id. + verifiedKeyIDs := make(map[string]struct{}) + numVerifiedKeys := 0 + for _, sig := range s.Signatures { + if !roleData.ValidKey(sig.KeyID) { + continue + } + verifier, err := db.GetVerifier(sig.KeyID) + if err != nil { + continue + } + + if err := VerifySignature(s.Signed, sig.Signature, verifier); err != nil { + // If a signature fails verification, don't count it towards the + // threshold but also return early and error out immediately. + // Note: Because of this, it is impossible to distinguish between + // an error of an invalid signature and a threshold not achieved. + // Invalid signatures lead to not achieving the threshold. + continue + } + + // Only consider this key valid if we haven't seen any of it's + // key ids before. + // Careful: we must not rely on the key IDs _declared in the file_, + // instead we get to decide what key IDs this key correspond to. + // XXX dangerous; better stop supporting multiple key IDs altogether. + keyIDs := verifier.MarshalPublicKey().IDs() + wasKeySeen := false + for _, keyID := range keyIDs { + if _, present := verifiedKeyIDs[keyID]; present { + wasKeySeen = true + } + } + if !wasKeySeen { + for _, id := range keyIDs { + verifiedKeyIDs[id] = struct{}{} + } + + numVerifiedKeys++ + } + } + if numVerifiedKeys < roleData.Threshold { + return ErrRoleThreshold{roleData.Threshold, numVerifiedKeys} + } + + return nil +} + +func (db *DB) Unmarshal(b []byte, v interface{}, role string, minVersion int64) error { + s := &data.Signed{} + if err := json.Unmarshal(b, s); err != nil { + return err + } + if err := db.Verify(s, role, minVersion); err != nil { + return err + } + return json.Unmarshal(s.Signed, v) +} + +// UnmarshalExpired is exactly like Unmarshal except ignores expired timestamp error. +func (db *DB) UnmarshalIgnoreExpired(b []byte, v interface{}, role string, minVersion int64) error { + s := &data.Signed{} + if err := json.Unmarshal(b, s); err != nil { + return err + } + // Note: If verification fails, then we wont attempt to unmarshal + // unless when verification error is errExpired. + verifyErr := db.Verify(s, role, minVersion) + if verifyErr != nil { + if _, ok := verifyErr.(ErrExpired); !ok { + return verifyErr + } + } + return json.Unmarshal(s.Signed, v) +} + +func (db *DB) UnmarshalTrusted(b []byte, v interface{}, role string) error { + s := &data.Signed{} + if err := json.Unmarshal(b, s); err != nil { + return err + } + if err := db.VerifySignatures(s, role); err != nil { + return err + } + return json.Unmarshal(s.Signed, v) +} diff --git a/vendor/github.com/DataDog/gostackparse/gostackparse.go b/vendor/github.com/DataDog/gostackparse/gostackparse.go index 4b2adb7da..b5292cfd3 100644 --- a/vendor/github.com/DataDog/gostackparse/gostackparse.go +++ b/vendor/github.com/DataDog/gostackparse/gostackparse.go @@ -214,6 +214,17 @@ func parseGoroutineHeader(line []byte) *Goroutine { func parseFunc(line []byte, state parserState) *Frame { // createdBy func calls don't have trailing parens, just return them as-is. if state == stateCreatedByFunc { + // go 1.21 changes the "created by" line to include the + // goroutine which created the one whose stack is being printed, + // e.g. + // created by main.main in goroutine 1 + // We are at the beginning of the function name, so we should + // just show up to the first space which follows the end of the + // function name. + i := bytes.Index(line, []byte(" ")) + if i > 0 { + return &Frame{Func: string(line[:i])} + } return &Frame{Func: string(line)} } diff --git a/vendor/github.com/DataDog/sketches-go/LICENSE b/vendor/github.com/DataDog/sketches-go/LICENSE new file mode 100644 index 000000000..7d3693bee --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/LICENSE @@ -0,0 +1,13 @@ +Copyright 2021 DataDog, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/vendor/github.com/DataDog/sketches-go/LICENSE-3rdparty.csv b/vendor/github.com/DataDog/sketches-go/LICENSE-3rdparty.csv new file mode 100644 index 000000000..db2f8cca0 --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/LICENSE-3rdparty.csv @@ -0,0 +1,3 @@ +Component,Origin,License +import (test),github.com/google/gofuzz,Apache-2.0 +import (test),github.com/stretchr/testify,MIT diff --git a/vendor/github.com/DataDog/sketches-go/NOTICE b/vendor/github.com/DataDog/sketches-go/NOTICE new file mode 100644 index 000000000..7ae253a01 --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/NOTICE @@ -0,0 +1,4 @@ +Datadog sketches-go +Copyright 2021 Datadog, Inc. + +This product includes software developed at Datadog (https://www.datadoghq.com/). diff --git a/vendor/github.com/DataDog/sketches-go/ddsketch/ddsketch.go b/vendor/github.com/DataDog/sketches-go/ddsketch/ddsketch.go new file mode 100644 index 000000000..33a0ea5b2 --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/ddsketch/ddsketch.go @@ -0,0 +1,767 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +package ddsketch + +import ( + "errors" + "io" + "math" + + enc "github.com/DataDog/sketches-go/ddsketch/encoding" + "github.com/DataDog/sketches-go/ddsketch/mapping" + "github.com/DataDog/sketches-go/ddsketch/pb/sketchpb" + "github.com/DataDog/sketches-go/ddsketch/stat" + "github.com/DataDog/sketches-go/ddsketch/store" +) + +var ( + ErrUntrackableNaN = errors.New("input value is NaN and cannot be tracked by the sketch") + ErrUntrackableTooLow = errors.New("input value is too low and cannot be tracked by the sketch") + ErrUntrackableTooHigh = errors.New("input value is too high and cannot be tracked by the sketch") + ErrNegativeCount = errors.New("count cannot be negative") + errEmptySketch = errors.New("no such element exists") + errUnknownFlag = errors.New("unknown encoding flag") +) + +// Unexported to prevent usage and avoid the cost of dynamic dispatch +type quantileSketch interface { + RelativeAccuracy() float64 + IsEmpty() bool + GetCount() float64 + GetZeroCount() float64 + GetSum() float64 + GetPositiveValueStore() store.Store + GetNegativeValueStore() store.Store + GetMinValue() (float64, error) + GetMaxValue() (float64, error) + GetValueAtQuantile(quantile float64) (float64, error) + GetValuesAtQuantiles(quantiles []float64) ([]float64, error) + ForEach(f func(value, count float64) (stop bool)) + Add(value float64) error + AddWithCount(value, count float64) error + // MergeWith + // ChangeMapping + Reweight(factor float64) error + Clear() + // Copy + Encode(b *[]byte, omitIndexMapping bool) + DecodeAndMergeWith(b []byte) error +} + +var _ quantileSketch = (*DDSketch)(nil) +var _ quantileSketch = (*DDSketchWithExactSummaryStatistics)(nil) + +type DDSketch struct { + mapping.IndexMapping + positiveValueStore store.Store + negativeValueStore store.Store + zeroCount float64 +} + +func NewDDSketchFromStoreProvider(indexMapping mapping.IndexMapping, storeProvider store.Provider) *DDSketch { + return NewDDSketch(indexMapping, storeProvider(), storeProvider()) +} + +func NewDDSketch(indexMapping mapping.IndexMapping, positiveValueStore store.Store, negativeValueStore store.Store) *DDSketch { + return &DDSketch{ + IndexMapping: indexMapping, + positiveValueStore: positiveValueStore, + negativeValueStore: negativeValueStore, + } +} + +func NewDefaultDDSketch(relativeAccuracy float64) (*DDSketch, error) { + m, err := mapping.NewDefaultMapping(relativeAccuracy) + if err != nil { + return nil, err + } + return NewDDSketchFromStoreProvider(m, store.DefaultProvider), nil +} + +// Constructs an instance of DDSketch that offers constant-time insertion and whose size grows indefinitely +// to accommodate for the range of input values. +func LogUnboundedDenseDDSketch(relativeAccuracy float64) (*DDSketch, error) { + indexMapping, err := mapping.NewLogarithmicMapping(relativeAccuracy) + if err != nil { + return nil, err + } + return NewDDSketch(indexMapping, store.NewDenseStore(), store.NewDenseStore()), nil +} + +// Constructs an instance of DDSketch that offers constant-time insertion and whose size grows until the +// maximum number of bins is reached, at which point bins with lowest indices are collapsed, which causes the +// relative accuracy guarantee to be lost on lowest quantiles if values are all positive, or the mid-range +// quantiles for values closest to zero if values include negative numbers. +func LogCollapsingLowestDenseDDSketch(relativeAccuracy float64, maxNumBins int) (*DDSketch, error) { + indexMapping, err := mapping.NewLogarithmicMapping(relativeAccuracy) + if err != nil { + return nil, err + } + return NewDDSketch(indexMapping, store.NewCollapsingLowestDenseStore(maxNumBins), store.NewCollapsingLowestDenseStore(maxNumBins)), nil +} + +// Constructs an instance of DDSketch that offers constant-time insertion and whose size grows until the +// maximum number of bins is reached, at which point bins with highest indices are collapsed, which causes the +// relative accuracy guarantee to be lost on highest quantiles if values are all positive, or the lowest and +// highest quantiles if values include negative numbers. +func LogCollapsingHighestDenseDDSketch(relativeAccuracy float64, maxNumBins int) (*DDSketch, error) { + indexMapping, err := mapping.NewLogarithmicMapping(relativeAccuracy) + if err != nil { + return nil, err + } + return NewDDSketch(indexMapping, store.NewCollapsingHighestDenseStore(maxNumBins), store.NewCollapsingHighestDenseStore(maxNumBins)), nil +} + +// Adds a value to the sketch. +func (s *DDSketch) Add(value float64) error { + return s.AddWithCount(value, float64(1)) +} + +// Adds a value to the sketch with a float64 count. +func (s *DDSketch) AddWithCount(value, count float64) error { + if count < 0 { + return ErrNegativeCount + } + + if value > s.MinIndexableValue() { + if value > s.MaxIndexableValue() { + return ErrUntrackableTooHigh + } + s.positiveValueStore.AddWithCount(s.Index(value), count) + } else if value < -s.MinIndexableValue() { + if value < -s.MaxIndexableValue() { + return ErrUntrackableTooLow + } + s.negativeValueStore.AddWithCount(s.Index(-value), count) + } else if math.IsNaN(value) { + return ErrUntrackableNaN + } else { + s.zeroCount += count + } + return nil +} + +// Return a (deep) copy of this sketch. +func (s *DDSketch) Copy() *DDSketch { + return &DDSketch{ + IndexMapping: s.IndexMapping, + positiveValueStore: s.positiveValueStore.Copy(), + negativeValueStore: s.negativeValueStore.Copy(), + zeroCount: s.zeroCount, + } +} + +// Clear empties the sketch while allowing reusing already allocated memory. +func (s *DDSketch) Clear() { + s.positiveValueStore.Clear() + s.negativeValueStore.Clear() + s.zeroCount = 0 +} + +// Return the value at the specified quantile. Return a non-nil error if the quantile is invalid +// or if the sketch is empty. +func (s *DDSketch) GetValueAtQuantile(quantile float64) (float64, error) { + if quantile < 0 || quantile > 1 { + return math.NaN(), errors.New("The quantile must be between 0 and 1.") + } + + count := s.GetCount() + if count == 0 { + return math.NaN(), errEmptySketch + } + + rank := quantile * (count - 1) + negativeValueCount := s.negativeValueStore.TotalCount() + if rank < negativeValueCount { + return -s.Value(s.negativeValueStore.KeyAtRank(negativeValueCount - 1 - rank)), nil + } else if rank < s.zeroCount+negativeValueCount { + return 0, nil + } else { + return s.Value(s.positiveValueStore.KeyAtRank(rank - s.zeroCount - negativeValueCount)), nil + } +} + +// Return the values at the respective specified quantiles. Return a non-nil error if any of the quantiles +// is invalid or if the sketch is empty. +func (s *DDSketch) GetValuesAtQuantiles(quantiles []float64) ([]float64, error) { + values := make([]float64, len(quantiles)) + for i, q := range quantiles { + val, err := s.GetValueAtQuantile(q) + if err != nil { + return nil, err + } + values[i] = val + } + return values, nil +} + +// Return the total number of values that have been added to this sketch. +func (s *DDSketch) GetCount() float64 { + return s.zeroCount + s.positiveValueStore.TotalCount() + s.negativeValueStore.TotalCount() +} + +// GetZeroCount returns the number of zero values that have been added to this sketch. +// Note: values that are very small (lower than MinIndexableValue if positive, or higher than -MinIndexableValue if negative) +// are also mapped to the zero bucket. +func (s *DDSketch) GetZeroCount() float64 { + return s.zeroCount +} + +// Return true iff no value has been added to this sketch. +func (s *DDSketch) IsEmpty() bool { + return s.zeroCount == 0 && s.positiveValueStore.IsEmpty() && s.negativeValueStore.IsEmpty() +} + +// Return the maximum value that has been added to this sketch. Return a non-nil error if the sketch +// is empty. +func (s *DDSketch) GetMaxValue() (float64, error) { + if !s.positiveValueStore.IsEmpty() { + maxIndex, _ := s.positiveValueStore.MaxIndex() + return s.Value(maxIndex), nil + } else if s.zeroCount > 0 { + return 0, nil + } else { + minIndex, err := s.negativeValueStore.MinIndex() + if err != nil { + return math.NaN(), err + } + return -s.Value(minIndex), nil + } +} + +// Return the minimum value that has been added to this sketch. Returns a non-nil error if the sketch +// is empty. +func (s *DDSketch) GetMinValue() (float64, error) { + if !s.negativeValueStore.IsEmpty() { + maxIndex, _ := s.negativeValueStore.MaxIndex() + return -s.Value(maxIndex), nil + } else if s.zeroCount > 0 { + return 0, nil + } else { + minIndex, err := s.positiveValueStore.MinIndex() + if err != nil { + return math.NaN(), err + } + return s.Value(minIndex), nil + } +} + +// GetSum returns an approximation of the sum of the values that have been added to the sketch. If the +// values that have been added to the sketch all have the same sign, the approximation error has +// the relative accuracy guarantees of the mapping used for this sketch. +func (s *DDSketch) GetSum() (sum float64) { + s.ForEach(func(value float64, count float64) (stop bool) { + sum += value * count + return false + }) + return sum +} + +// GetPositiveValueStore returns the store.Store object that contains the positive +// values of the sketch. +func (s *DDSketch) GetPositiveValueStore() store.Store { + return s.positiveValueStore +} + +// GetNegativeValueStore returns the store.Store object that contains the negative +// values of the sketch. +func (s *DDSketch) GetNegativeValueStore() store.Store { + return s.negativeValueStore +} + +// ForEach applies f on the bins of the sketches until f returns true. +// There is no guarantee on the bin iteration order. +func (s *DDSketch) ForEach(f func(value, count float64) (stop bool)) { + if s.zeroCount != 0 && f(0, s.zeroCount) { + return + } + stopped := false + s.positiveValueStore.ForEach(func(index int, count float64) bool { + stopped = f(s.IndexMapping.Value(index), count) + return stopped + }) + if stopped { + return + } + s.negativeValueStore.ForEach(func(index int, count float64) bool { + return f(-s.IndexMapping.Value(index), count) + }) +} + +// Merges the other sketch into this one. After this operation, this sketch encodes the values that +// were added to both this and the other sketches. +func (s *DDSketch) MergeWith(other *DDSketch) error { + if !s.IndexMapping.Equals(other.IndexMapping) { + return errors.New("Cannot merge sketches with different index mappings.") + } + s.positiveValueStore.MergeWith(other.positiveValueStore) + s.negativeValueStore.MergeWith(other.negativeValueStore) + s.zeroCount += other.zeroCount + return nil +} + +// Generates a protobuf representation of this DDSketch. +func (s *DDSketch) ToProto() *sketchpb.DDSketch { + return &sketchpb.DDSketch{ + Mapping: s.IndexMapping.ToProto(), + PositiveValues: s.positiveValueStore.ToProto(), + NegativeValues: s.negativeValueStore.ToProto(), + ZeroCount: s.zeroCount, + } +} + +// FromProto builds a new instance of DDSketch based on the provided protobuf representation, using a Dense store. +func FromProto(pb *sketchpb.DDSketch) (*DDSketch, error) { + return FromProtoWithStoreProvider(pb, store.DenseStoreConstructor) +} + +func FromProtoWithStoreProvider(pb *sketchpb.DDSketch, storeProvider store.Provider) (*DDSketch, error) { + positiveValueStore := storeProvider() + if pb.PositiveValues != nil { + store.MergeWithProto(positiveValueStore, pb.PositiveValues) + } + negativeValueStore := storeProvider() + if pb.NegativeValues != nil { + store.MergeWithProto(negativeValueStore, pb.NegativeValues) + } + m, err := mapping.FromProto(pb.Mapping) + if err != nil { + return nil, err + } + return &DDSketch{ + IndexMapping: m, + positiveValueStore: positiveValueStore, + negativeValueStore: negativeValueStore, + zeroCount: pb.ZeroCount, + }, nil +} + +// Encode serializes the sketch and appends the serialized content to the provided []byte. +// If the capacity of the provided []byte is large enough, Encode does not allocate memory space. +// When the index mapping is known at the time of deserialization, omitIndexMapping can be set to true to avoid encoding it and to make the serialized content smaller. +// The encoding format is described in the encoding/flag module. +func (s *DDSketch) Encode(b *[]byte, omitIndexMapping bool) { + if s.zeroCount != 0 { + enc.EncodeFlag(b, enc.FlagZeroCountVarFloat) + enc.EncodeVarfloat64(b, s.zeroCount) + } + + if !omitIndexMapping { + s.IndexMapping.Encode(b) + } + + s.positiveValueStore.Encode(b, enc.FlagTypePositiveStore) + s.negativeValueStore.Encode(b, enc.FlagTypeNegativeStore) +} + +// DecodeDDSketch deserializes a sketch. +// Stores are built using storeProvider. The store type needs not match the +// store that the serialized sketch initially used. However, using the same +// store type may make decoding faster. In the absence of high performance +// requirements, store.BufferedPaginatedStoreConstructor is a sound enough +// choice of store provider. +// To avoid memory allocations, it is possible to use a store provider that +// reuses stores, by calling Clear() on previously used stores before providing +// the store. +// If the serialized data does not contain the index mapping, you need to +// specify the index mapping that was used in the sketch that was encoded. +// Otherwise, you can use nil and the index mapping will be decoded from the +// serialized data. +// It is possible to decode with this function an encoded +// DDSketchWithExactSummaryStatistics, but the exact summary statistics will be +// lost. +func DecodeDDSketch(b []byte, storeProvider store.Provider, indexMapping mapping.IndexMapping) (*DDSketch, error) { + s := &DDSketch{ + IndexMapping: indexMapping, + positiveValueStore: storeProvider(), + negativeValueStore: storeProvider(), + zeroCount: float64(0), + } + err := s.DecodeAndMergeWith(b) + return s, err +} + +// DecodeAndMergeWith deserializes a sketch and merges its content in the +// receiver sketch. +// If the serialized content contains an index mapping that differs from the one +// of the receiver, DecodeAndMergeWith returns an error. +func (s *DDSketch) DecodeAndMergeWith(bb []byte) error { + return s.decodeAndMergeWith(bb, func(b *[]byte, flag enc.Flag) error { + switch flag { + case enc.FlagCount, enc.FlagSum, enc.FlagMin, enc.FlagMax: + // Exact summary stats are ignored. + if len(*b) < 8 { + return io.EOF + } + *b = (*b)[8:] + return nil + default: + return errUnknownFlag + } + }) +} + +func (s *DDSketch) decodeAndMergeWith(bb []byte, fallbackDecode func(b *[]byte, flag enc.Flag) error) error { + b := &bb + for len(*b) > 0 { + flag, err := enc.DecodeFlag(b) + if err != nil { + return err + } + switch flag.Type() { + case enc.FlagTypePositiveStore: + s.positiveValueStore.DecodeAndMergeWith(b, flag.SubFlag()) + case enc.FlagTypeNegativeStore: + s.negativeValueStore.DecodeAndMergeWith(b, flag.SubFlag()) + case enc.FlagTypeIndexMapping: + decodedIndexMapping, err := mapping.Decode(b, flag) + if err != nil { + return err + } + if s.IndexMapping != nil && !s.IndexMapping.Equals(decodedIndexMapping) { + return errors.New("index mapping mismatch") + } + s.IndexMapping = decodedIndexMapping + default: + switch flag { + + case enc.FlagZeroCountVarFloat: + decodedZeroCount, err := enc.DecodeVarfloat64(b) + if err != nil { + return err + } + s.zeroCount += decodedZeroCount + + default: + err := fallbackDecode(b, flag) + if err != nil { + return err + } + } + } + } + + if s.IndexMapping == nil { + return errors.New("missing index mapping") + } + return nil +} + +// ChangeMapping changes the store to a new mapping. +// it doesn't change s but returns a newly created sketch. +// positiveStore and negativeStore must be different stores, and be empty when the function is called. +// It is not the conversion that minimizes the loss in relative +// accuracy, but it avoids artefacts like empty bins that make the histograms look bad. +// scaleFactor allows to scale out / in all values. (changing units for eg) +func (s *DDSketch) ChangeMapping(newMapping mapping.IndexMapping, positiveStore store.Store, negativeStore store.Store, scaleFactor float64) *DDSketch { + if scaleFactor == 1 && s.IndexMapping.Equals(newMapping) { + return s.Copy() + } + changeStoreMapping(s.IndexMapping, newMapping, s.positiveValueStore, positiveStore, scaleFactor) + changeStoreMapping(s.IndexMapping, newMapping, s.negativeValueStore, negativeStore, scaleFactor) + newSketch := NewDDSketch(newMapping, positiveStore, negativeStore) + newSketch.zeroCount = s.zeroCount + return newSketch +} + +func changeStoreMapping(oldMapping, newMapping mapping.IndexMapping, oldStore, newStore store.Store, scaleFactor float64) { + oldStore.ForEach(func(index int, count float64) (stop bool) { + inLowerBound := oldMapping.LowerBound(index) * scaleFactor + inHigherBound := oldMapping.LowerBound(index+1) * scaleFactor + inSize := inHigherBound - inLowerBound + for outIndex := newMapping.Index(inLowerBound); newMapping.LowerBound(outIndex) < inHigherBound; outIndex++ { + outLowerBound := newMapping.LowerBound(outIndex) + outHigherBound := newMapping.LowerBound(outIndex + 1) + lowerIntersectionBound := math.Max(outLowerBound, inLowerBound) + higherIntersectionBound := math.Min(outHigherBound, inHigherBound) + intersectionSize := higherIntersectionBound - lowerIntersectionBound + proportion := intersectionSize / inSize + newStore.AddWithCount(outIndex, proportion*count) + } + return false + }) +} + +// Reweight multiplies all values from the sketch by w, but keeps the same global distribution. +// w has to be strictly greater than 0. +func (s *DDSketch) Reweight(w float64) error { + if w <= 0 { + return errors.New("can't reweight by a negative factor") + } + if w == 1 { + return nil + } + s.zeroCount *= w + if err := s.positiveValueStore.Reweight(w); err != nil { + return err + } + if err := s.negativeValueStore.Reweight(w); err != nil { + return err + } + return nil +} + +// DDSketchWithExactSummaryStatistics returns exact count, sum, min and max, as +// opposed to DDSketch, which may return approximate values for those +// statistics. Because of the need to track them exactly, adding and merging +// operations are slightly more exepensive than those of DDSketch. +type DDSketchWithExactSummaryStatistics struct { + *DDSketch + summaryStatistics *stat.SummaryStatistics +} + +func NewDefaultDDSketchWithExactSummaryStatistics(relativeAccuracy float64) (*DDSketchWithExactSummaryStatistics, error) { + sketch, err := NewDefaultDDSketch(relativeAccuracy) + if err != nil { + return nil, err + } + return &DDSketchWithExactSummaryStatistics{ + DDSketch: sketch, + summaryStatistics: stat.NewSummaryStatistics(), + }, nil +} + +func NewDDSketchWithExactSummaryStatistics(mapping mapping.IndexMapping, storeProvider store.Provider) *DDSketchWithExactSummaryStatistics { + return &DDSketchWithExactSummaryStatistics{ + DDSketch: NewDDSketchFromStoreProvider(mapping, storeProvider), + summaryStatistics: stat.NewSummaryStatistics(), + } +} + +// NewDDSketchWithExactSummaryStatisticsFromData constructs DDSketchWithExactSummaryStatistics from the provided sketch and exact summary statistics. +func NewDDSketchWithExactSummaryStatisticsFromData(sketch *DDSketch, summaryStatistics *stat.SummaryStatistics) (*DDSketchWithExactSummaryStatistics, error) { + if sketch.IsEmpty() != (summaryStatistics.Count() == 0) { + return nil, errors.New("sketch and summary statistics do not match") + } + return &DDSketchWithExactSummaryStatistics{ + DDSketch: sketch, + summaryStatistics: summaryStatistics, + }, nil +} + +func (s *DDSketchWithExactSummaryStatistics) IsEmpty() bool { + return s.summaryStatistics.Count() == 0 +} + +func (s *DDSketchWithExactSummaryStatistics) GetCount() float64 { + return s.summaryStatistics.Count() +} + +// GetZeroCount returns the number of zero values that have been added to this sketch. +// Note: values that are very small (lower than MinIndexableValue if positive, or higher than -MinIndexableValue if negative) +// are also mapped to the zero bucket. +func (s *DDSketchWithExactSummaryStatistics) GetZeroCount() float64 { + return s.DDSketch.zeroCount +} + +func (s *DDSketchWithExactSummaryStatistics) GetSum() float64 { + return s.summaryStatistics.Sum() +} + +// GetPositiveValueStore returns the store.Store object that contains the positive +// values of the sketch. +func (s *DDSketchWithExactSummaryStatistics) GetPositiveValueStore() store.Store { + return s.DDSketch.positiveValueStore +} + +// GetNegativeValueStore returns the store.Store object that contains the negative +// values of the sketch. +func (s *DDSketchWithExactSummaryStatistics) GetNegativeValueStore() store.Store { + return s.DDSketch.negativeValueStore +} + +func (s *DDSketchWithExactSummaryStatistics) GetMinValue() (float64, error) { + if s.DDSketch.IsEmpty() { + return math.NaN(), errEmptySketch + } + return s.summaryStatistics.Min(), nil +} + +func (s *DDSketchWithExactSummaryStatistics) GetMaxValue() (float64, error) { + if s.DDSketch.IsEmpty() { + return math.NaN(), errEmptySketch + } + return s.summaryStatistics.Max(), nil +} + +func (s *DDSketchWithExactSummaryStatistics) GetValueAtQuantile(quantile float64) (float64, error) { + value, err := s.DDSketch.GetValueAtQuantile(quantile) + min := s.summaryStatistics.Min() + if value < min { + return min, err + } + max := s.summaryStatistics.Max() + if value > max { + return max, err + } + return value, err +} + +func (s *DDSketchWithExactSummaryStatistics) GetValuesAtQuantiles(quantiles []float64) ([]float64, error) { + values, err := s.DDSketch.GetValuesAtQuantiles(quantiles) + min := s.summaryStatistics.Min() + max := s.summaryStatistics.Max() + for i := range values { + if values[i] < min { + values[i] = min + } else if values[i] > max { + values[i] = max + } + } + return values, err +} + +func (s *DDSketchWithExactSummaryStatistics) ForEach(f func(value, count float64) (stop bool)) { + s.DDSketch.ForEach(f) +} + +func (s *DDSketchWithExactSummaryStatistics) Clear() { + s.DDSketch.Clear() + s.summaryStatistics.Clear() +} + +func (s *DDSketchWithExactSummaryStatistics) Add(value float64) error { + err := s.DDSketch.Add(value) + if err != nil { + return err + } + s.summaryStatistics.Add(value, 1) + return nil +} + +func (s *DDSketchWithExactSummaryStatistics) AddWithCount(value, count float64) error { + if count == 0 { + return nil + } + err := s.DDSketch.AddWithCount(value, count) + if err != nil { + return err + } + s.summaryStatistics.Add(value, count) + return nil +} + +func (s *DDSketchWithExactSummaryStatistics) MergeWith(o *DDSketchWithExactSummaryStatistics) error { + err := s.DDSketch.MergeWith(o.DDSketch) + if err != nil { + return err + } + s.summaryStatistics.MergeWith(o.summaryStatistics) + return nil +} + +func (s *DDSketchWithExactSummaryStatistics) Copy() *DDSketchWithExactSummaryStatistics { + return &DDSketchWithExactSummaryStatistics{ + DDSketch: s.DDSketch.Copy(), + summaryStatistics: s.summaryStatistics.Copy(), + } +} + +func (s *DDSketchWithExactSummaryStatistics) Reweight(factor float64) error { + err := s.DDSketch.Reweight(factor) + if err != nil { + return err + } + s.summaryStatistics.Reweight(factor) + return nil +} + +func (s *DDSketchWithExactSummaryStatistics) ChangeMapping(newMapping mapping.IndexMapping, storeProvider store.Provider, scaleFactor float64) *DDSketchWithExactSummaryStatistics { + summaryStatisticsCopy := s.summaryStatistics.Copy() + summaryStatisticsCopy.Rescale(scaleFactor) + return &DDSketchWithExactSummaryStatistics{ + DDSketch: s.DDSketch.ChangeMapping(newMapping, storeProvider(), storeProvider(), scaleFactor), + summaryStatistics: summaryStatisticsCopy, + } +} + +func (s *DDSketchWithExactSummaryStatistics) Encode(b *[]byte, omitIndexMapping bool) { + if s.summaryStatistics.Count() != 0 { + enc.EncodeFlag(b, enc.FlagCount) + enc.EncodeVarfloat64(b, s.summaryStatistics.Count()) + } + if s.summaryStatistics.Sum() != 0 { + enc.EncodeFlag(b, enc.FlagSum) + enc.EncodeFloat64LE(b, s.summaryStatistics.Sum()) + } + if s.summaryStatistics.Min() != math.Inf(1) { + enc.EncodeFlag(b, enc.FlagMin) + enc.EncodeFloat64LE(b, s.summaryStatistics.Min()) + } + if s.summaryStatistics.Max() != math.Inf(-1) { + enc.EncodeFlag(b, enc.FlagMax) + enc.EncodeFloat64LE(b, s.summaryStatistics.Max()) + } + s.DDSketch.Encode(b, omitIndexMapping) +} + +// DecodeDDSketchWithExactSummaryStatistics deserializes a sketch. +// Stores are built using storeProvider. The store type needs not match the +// store that the serialized sketch initially used. However, using the same +// store type may make decoding faster. In the absence of high performance +// requirements, store.DefaultProvider is a sound enough choice of store +// provider. +// To avoid memory allocations, it is possible to use a store provider that +// reuses stores, by calling Clear() on previously used stores before providing +// the store. +// If the serialized data does not contain the index mapping, you need to +// specify the index mapping that was used in the sketch that was encoded. +// Otherwise, you can use nil and the index mapping will be decoded from the +// serialized data. +// It is not possible to decode with this function an encoded DDSketch (unless +// it is empty), because it does not track exact summary statistics +func DecodeDDSketchWithExactSummaryStatistics(b []byte, storeProvider store.Provider, indexMapping mapping.IndexMapping) (*DDSketchWithExactSummaryStatistics, error) { + s := &DDSketchWithExactSummaryStatistics{ + DDSketch: &DDSketch{ + IndexMapping: indexMapping, + positiveValueStore: storeProvider(), + negativeValueStore: storeProvider(), + zeroCount: float64(0), + }, + summaryStatistics: stat.NewSummaryStatistics(), + } + err := s.DecodeAndMergeWith(b) + return s, err +} + +func (s *DDSketchWithExactSummaryStatistics) DecodeAndMergeWith(bb []byte) error { + err := s.DDSketch.decodeAndMergeWith(bb, func(b *[]byte, flag enc.Flag) error { + switch flag { + case enc.FlagCount: + count, err := enc.DecodeVarfloat64(b) + if err != nil { + return err + } + s.summaryStatistics.AddToCount(count) + return nil + case enc.FlagSum: + sum, err := enc.DecodeFloat64LE(b) + if err != nil { + return err + } + s.summaryStatistics.AddToSum(sum) + return nil + case enc.FlagMin, enc.FlagMax: + stat, err := enc.DecodeFloat64LE(b) + if err != nil { + return err + } + s.summaryStatistics.Add(stat, 0) + return nil + default: + return errUnknownFlag + } + }) + if err != nil { + return err + } + // It is assumed that if the count is encoded, other exact summary + // statistics are encoded as well, which is the case if Encode is used. + if s.summaryStatistics.Count() == 0 && !s.DDSketch.IsEmpty() { + return errors.New("missing exact summary statistics") + } + return nil +} diff --git a/vendor/github.com/DataDog/sketches-go/ddsketch/encoding/encoding.go b/vendor/github.com/DataDog/sketches-go/ddsketch/encoding/encoding.go new file mode 100644 index 000000000..c50dc1adb --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/ddsketch/encoding/encoding.go @@ -0,0 +1,208 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +package encoding + +import ( + "encoding/binary" + "errors" + "io" + "math" + "math/bits" +) + +// Encoding functions append bytes to the provided *[]byte, allowing avoiding +// allocations if the slice initially has a large enough capacity. +// Decoding functions also take *[]byte as input, and when they do not return an +// error, advance the slice so that it starts at the immediate byte after the +// decoded part (or so that it is empty if there is no such byte). + +const ( + MaxVarLen64 = 9 + varfloat64Rotate = 6 +) + +var uvarint64Sizes = initUvarint64Sizes() +var varfloat64Sizes = initVarfloat64Sizes() + +// EncodeUvarint64 serializes 64-bit unsigned integers 7 bits at a time, +// starting with the least significant bits. The most significant bit in each +// output byte is the continuation bit and indicates whether there are +// additional non-zero bits encoded in following bytes. There are at most 9 +// output bytes and the last one does not have a continuation bit, allowing for +// it to encode 8 bits (8*7+8 = 64). +func EncodeUvarint64(b *[]byte, v uint64) { + for i := 0; i < MaxVarLen64-1; i++ { + if v < 0x80 { + break + } + *b = append(*b, byte(v)|byte(0x80)) + v >>= 7 + } + *b = append(*b, byte(v)) +} + +// DecodeUvarint64 deserializes 64-bit unsigned integers that have been encoded +// using EncodeUvarint64. +func DecodeUvarint64(b *[]byte) (uint64, error) { + x := uint64(0) + s := uint(0) + for i := 0; ; i++ { + if len(*b) <= i { + return 0, io.EOF + } + n := (*b)[i] + if n < 0x80 || i == MaxVarLen64-1 { + *b = (*b)[i+1:] + return x | uint64(n)<>i) + sizes[i] = len(b) + } + return sizes +} + +// EncodeVarint64 serializes 64-bit signed integers using zig-zag encoding, +// which ensures small-scale integers are turned into unsigned integers that +// have leading zeros, whether they are positive or negative, hence allows for +// space-efficient varuint encoding of those values. +func EncodeVarint64(b *[]byte, v int64) { + EncodeUvarint64(b, uint64(v>>(64-1)^(v<<1))) +} + +// DecodeVarint64 deserializes 64-bit signed integers that have been encoded +// using EncodeVarint32. +func DecodeVarint64(b *[]byte) (int64, error) { + v, err := DecodeUvarint64(b) + return int64((v >> 1) ^ -(v & 1)), err +} + +// Varint64Size returns the number of bytes that EncodeVarint64 encodes a 64-bit +// signed integer into. +func Varint64Size(v int64) int { + return Uvarint64Size(uint64(v>>(64-1) ^ (v << 1))) +} + +var errVarint32Overflow = errors.New("varint overflows a 32-bit integer") + +// DecodeVarint32 deserializes 32-bit signed integers that have been encoded +// using EncodeVarint64. +func DecodeVarint32(b *[]byte) (int32, error) { + v, err := DecodeVarint64(b) + if err != nil { + return 0, err + } + if v > math.MaxInt32 || v < math.MinInt32 { + return 0, errVarint32Overflow + } + return int32(v), nil +} + +// EncodeFloat64LE serializes 64-bit floating-point values, starting with the +// least significant bytes. +func EncodeFloat64LE(b *[]byte, v float64) { + *b = append(*b, make([]byte, 8)...) + binary.LittleEndian.PutUint64((*b)[len(*b)-8:], math.Float64bits(v)) +} + +// DecodeFloat64LE deserializes 64-bit floating-point values that have been +// encoded with EncodeFloat64LE. +func DecodeFloat64LE(b *[]byte) (float64, error) { + if len(*b) < 8 { + return 0, io.EOF + } + v := math.Float64frombits(binary.LittleEndian.Uint64(*b)) + *b = (*b)[8:] + return v, nil +} + +// EncodeVarfloat64 serializes 64-bit floating-point values using a method that +// is similar to the varuint encoding and that is space-efficient for +// non-negative integer values. The output takes at most 9 bytes. +// Input values are first shifted as floating-point values (+1), then transmuted +// to integer values, then shifted again as integer values (-Float64bits(1)). +// That is in order to minimize the number of non-zero bits when dealing with +// non-negative integer values. +// After that transformation, any input integer value no greater than 2^53 (the +// largest integer value that can be encoded exactly as a 64-bit floating-point +// value) will have at least 6 leading zero bits. By rotating bits to the left, +// those bits end up at the right of the binary representation. +// The resulting bits are then encoded similarly to the varuint method, but +// starting with the most significant bits. +func EncodeVarfloat64(b *[]byte, v float64) { + x := bits.RotateLeft64(math.Float64bits(v+1)-math.Float64bits(1), varfloat64Rotate) + for i := 0; i < MaxVarLen64-1; i++ { + n := byte(x >> (8*8 - 7)) + x <<= 7 + if x == 0 { + *b = append(*b, n) + return + } + *b = append(*b, n|byte(0x80)) + } + n := byte(x >> (8 * 7)) + *b = append(*b, n) +} + +// DecodeVarfloat64 deserializes 64-bit floating-point values that have been +// encoded with EncodeVarfloat64. +func DecodeVarfloat64(b *[]byte) (float64, error) { + x := uint64(0) + i := int(0) + s := uint(8*8 - 7) + for { + if len(*b) <= i { + return 0, io.EOF + } + n := (*b)[i] + if i == MaxVarLen64-1 { + x |= uint64(n) + break + } + if n < 0x80 { + x |= uint64(n) << s + break + } + x |= uint64(n&0x7F) << s + i++ + s -= 7 + } + *b = (*b)[i+1:] + return math.Float64frombits(bits.RotateLeft64(x, -varfloat64Rotate)+math.Float64bits(1)) - 1, nil +} + +// Varfloat64Size returns the number of bytes that EncodeVarfloat64 encodes a +// 64-bit floating-point value into. +func Varfloat64Size(v float64) int { + x := bits.RotateLeft64(math.Float64bits(v+1)-math.Float64bits(1), varfloat64Rotate) + return varfloat64Sizes[bits.TrailingZeros64(x)] +} + +func initVarfloat64Sizes() [65]int { + var sizes [65]int + b := []byte{} + for i := 0; i <= 64; i++ { + b = b[:0] + EncodeVarfloat64(&b, math.Float64frombits(bits.RotateLeft64(^uint64(0)<>exponentShift) - exponentBias) +} + +func getSignificandPlusOne(float64Bits uint64) float64 { + return math.Float64frombits((float64Bits & significandMask) | oneMask) +} + +// exponent should be >= -1022 and <= 1023 +// significandPlusOne should be >= 1 and < 2 +func buildFloat64(exponent int, significandPlusOne float64) float64 { + return math.Float64frombits( + (uint64((exponent+exponentBias)<sketches-java +type CubicallyInterpolatedMapping struct { + gamma float64 // base + indexOffset float64 + multiplier float64 // precomputed for performance + minIndexableValue float64 + maxIndexableValue float64 +} + +func NewCubicallyInterpolatedMapping(relativeAccuracy float64) (*CubicallyInterpolatedMapping, error) { + if relativeAccuracy <= 0 || relativeAccuracy >= 1 { + return nil, errors.New("The relative accuracy must be between 0 and 1.") + } + gamma := math.Pow((1+relativeAccuracy)/(1-relativeAccuracy), 10*math.Ln2/7) // > 1 + m, _ := NewCubicallyInterpolatedMappingWithGamma(gamma, 0) + return m, nil +} + +func NewCubicallyInterpolatedMappingWithGamma(gamma, indexOffset float64) (*CubicallyInterpolatedMapping, error) { + if gamma <= 1 { + return nil, errors.New("Gamma must be greater than 1.") + } + multiplier := 1 / math.Log2(gamma) + adjustedGamma := math.Pow(gamma, 7/(10*math.Ln2)) + m := CubicallyInterpolatedMapping{ + gamma: gamma, + indexOffset: indexOffset, + multiplier: multiplier, + minIndexableValue: math.Max( + math.Exp2((math.MinInt32-indexOffset)/multiplier+1), // so that index >= MinInt32 + minNormalFloat64*adjustedGamma, + ), + maxIndexableValue: math.Min( + math.Exp2((math.MaxInt32-indexOffset)/multiplier-1), // so that index <= MaxInt32 + math.Exp(expOverflow)/(2*adjustedGamma)*(adjustedGamma+1), // so that math.Exp does not overflow + ), + } + return &m, nil +} + +func (m *CubicallyInterpolatedMapping) Equals(other IndexMapping) bool { + o, ok := other.(*CubicallyInterpolatedMapping) + if !ok { + return false + } + tol := 1e-12 + return withinTolerance(m.gamma, o.gamma, tol) && withinTolerance(m.indexOffset, o.indexOffset, tol) +} + +func (m *CubicallyInterpolatedMapping) Index(value float64) int { + index := m.approximateLog(value)*m.multiplier + m.indexOffset + if index >= 0 { + return int(index) + } else { + return int(index) - 1 + } +} + +func (m *CubicallyInterpolatedMapping) Value(index int) float64 { + return m.LowerBound(index) * (1 + m.RelativeAccuracy()) +} + +func (m *CubicallyInterpolatedMapping) LowerBound(index int) float64 { + return m.approximateInverseLog((float64(index) - m.indexOffset) / m.multiplier) +} + +// Return an approximation of Math.log(x) / Math.log(base(2)). +func (m *CubicallyInterpolatedMapping) approximateLog(x float64) float64 { + bits := math.Float64bits(x) + e := getExponent(bits) + s := getSignificandPlusOne(bits) - 1 + return ((A*s+B)*s+C)*s + e +} + +// The exact inverse of approximateLog. +func (m *CubicallyInterpolatedMapping) approximateInverseLog(x float64) float64 { + exponent := math.Floor(x) + // Derived from Cardano's formula + d0 := B*B - 3*A*C + d1 := 2*B*B*B - 9*A*B*C - 27*A*A*(x-exponent) + p := math.Cbrt((d1 - math.Sqrt(d1*d1-4*d0*d0*d0)) / 2) + significandPlusOne := -(B+p+d0/p)/(3*A) + 1 + return buildFloat64(int(exponent), significandPlusOne) +} + +func (m *CubicallyInterpolatedMapping) MinIndexableValue() float64 { + return m.minIndexableValue +} + +func (m *CubicallyInterpolatedMapping) MaxIndexableValue() float64 { + return m.maxIndexableValue +} + +func (m *CubicallyInterpolatedMapping) RelativeAccuracy() float64 { + return 1 - 2/(1+math.Exp(7.0/10*math.Log2(m.gamma))) +} + +func (m *CubicallyInterpolatedMapping) ToProto() *sketchpb.IndexMapping { + return &sketchpb.IndexMapping{ + Gamma: m.gamma, + IndexOffset: m.indexOffset, + Interpolation: sketchpb.IndexMapping_CUBIC, + } +} + +func (m *CubicallyInterpolatedMapping) Encode(b *[]byte) { + enc.EncodeFlag(b, enc.FlagIndexMappingBaseCubic) + enc.EncodeFloat64LE(b, m.gamma) + enc.EncodeFloat64LE(b, m.indexOffset) +} + +func (m *CubicallyInterpolatedMapping) string() string { + var buffer bytes.Buffer + buffer.WriteString(fmt.Sprintf("gamma: %v, indexOffset: %v\n", m.gamma, m.indexOffset)) + return buffer.String() +} + +var _ IndexMapping = (*CubicallyInterpolatedMapping)(nil) diff --git a/vendor/github.com/DataDog/sketches-go/ddsketch/mapping/index_mapping.go b/vendor/github.com/DataDog/sketches-go/ddsketch/mapping/index_mapping.go new file mode 100644 index 000000000..88b926592 --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/ddsketch/mapping/index_mapping.go @@ -0,0 +1,95 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +package mapping + +import ( + "errors" + "fmt" + + enc "github.com/DataDog/sketches-go/ddsketch/encoding" + "github.com/DataDog/sketches-go/ddsketch/pb/sketchpb" +) + +const ( + expOverflow = 7.094361393031e+02 // The value at which math.Exp overflows + minNormalFloat64 = 2.2250738585072014e-308 //2^(-1022) +) + +type IndexMapping interface { + Equals(other IndexMapping) bool + Index(value float64) int + Value(index int) float64 + LowerBound(index int) float64 + RelativeAccuracy() float64 + // MinIndexableValue returns the minimum positive value that can be mapped to an index. + MinIndexableValue() float64 + // MaxIndexableValue returns the maximum positive value that can be mapped to an index. + MaxIndexableValue() float64 + ToProto() *sketchpb.IndexMapping + // Encode encodes a mapping and appends its content to the provided []byte. + Encode(b *[]byte) +} + +func NewDefaultMapping(relativeAccuracy float64) (IndexMapping, error) { + return NewLogarithmicMapping(relativeAccuracy) +} + +// FromProto returns an Index mapping from the protobuf definition of it +func FromProto(m *sketchpb.IndexMapping) (IndexMapping, error) { + if m == nil { + return nil, errors.New("cannot create IndexMapping from nil protobuf index mapping") + } + switch m.Interpolation { + case sketchpb.IndexMapping_NONE: + return NewLogarithmicMappingWithGamma(m.Gamma, m.IndexOffset) + case sketchpb.IndexMapping_LINEAR: + return NewLinearlyInterpolatedMappingWithGamma(m.Gamma, m.IndexOffset) + case sketchpb.IndexMapping_CUBIC: + return NewCubicallyInterpolatedMappingWithGamma(m.Gamma, m.IndexOffset) + default: + return nil, fmt.Errorf("interpolation not supported: %d", m.Interpolation) + } +} + +// Decode decodes a mapping and updates the provided []byte so that it starts +// immediately after the encoded mapping. +func Decode(b *[]byte, flag enc.Flag) (IndexMapping, error) { + switch flag { + + case enc.FlagIndexMappingBaseLogarithmic: + gamma, indexOffset, err := decodeLogLikeIndexMapping(b) + if err != nil { + return nil, err + } + return NewLogarithmicMappingWithGamma(gamma, indexOffset) + + case enc.FlagIndexMappingBaseLinear: + gamma, indexOffset, err := decodeLogLikeIndexMapping(b) + if err != nil { + return nil, err + } + return NewLinearlyInterpolatedMappingWithGamma(gamma, indexOffset) + + case enc.FlagIndexMappingBaseCubic: + gamma, indexOffset, err := decodeLogLikeIndexMapping(b) + if err != nil { + return nil, err + } + return NewCubicallyInterpolatedMappingWithGamma(gamma, indexOffset) + + default: + return nil, errors.New("unknown mapping") + } +} + +func decodeLogLikeIndexMapping(b *[]byte) (gamma, indexOffset float64, err error) { + gamma, err = enc.DecodeFloat64LE(b) + if err != nil { + return + } + indexOffset, err = enc.DecodeFloat64LE(b) + return +} diff --git a/vendor/github.com/DataDog/sketches-go/ddsketch/mapping/linearly_interpolated_mapping.go b/vendor/github.com/DataDog/sketches-go/ddsketch/mapping/linearly_interpolated_mapping.go new file mode 100644 index 000000000..d9b0b7408 --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/ddsketch/mapping/linearly_interpolated_mapping.go @@ -0,0 +1,142 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +package mapping + +import ( + "bytes" + "errors" + "fmt" + "math" + + enc "github.com/DataDog/sketches-go/ddsketch/encoding" + "github.com/DataDog/sketches-go/ddsketch/pb/sketchpb" +) + +// LinearlyInterpolatedMapping is a fast IndexMapping that approximates the +// memory-optimal LogarithmicMapping by extracting the floor value of the +// logarithm to the base 2 from the binary representations of floating-point +// values and linearly interpolating the logarithm in-between. +type LinearlyInterpolatedMapping struct { + gamma float64 // base + indexOffset float64 + multiplier float64 // precomputed for performance + minIndexableValue float64 + maxIndexableValue float64 +} + +func NewLinearlyInterpolatedMapping(relativeAccuracy float64) (*LinearlyInterpolatedMapping, error) { + if relativeAccuracy <= 0 || relativeAccuracy >= 1 { + return nil, errors.New("The relative accuracy must be between 0 and 1.") + } + gamma := math.Pow((1+relativeAccuracy)/(1-relativeAccuracy), math.Ln2) // > 1 + indexOffset := 1 / math.Log2(gamma) // for backward compatibility + m, _ := NewLinearlyInterpolatedMappingWithGamma(gamma, indexOffset) + return m, nil +} + +func NewLinearlyInterpolatedMappingWithGamma(gamma, indexOffset float64) (*LinearlyInterpolatedMapping, error) { + if gamma <= 1 { + return nil, errors.New("Gamma must be greater than 1.") + } + multiplier := 1 / math.Log2(gamma) + adjustedGamma := math.Pow(gamma, 1/math.Ln2) + m := LinearlyInterpolatedMapping{ + gamma: gamma, + indexOffset: indexOffset, + multiplier: multiplier, + minIndexableValue: math.Max( + math.Exp2((math.MinInt32-indexOffset)/multiplier+1), // so that index >= MinInt32 + minNormalFloat64*adjustedGamma, + ), + maxIndexableValue: math.Min( + math.Exp2((math.MaxInt32-indexOffset)/multiplier-1), // so that index <= MaxInt32 + math.Exp(expOverflow)/(2*adjustedGamma)*(adjustedGamma+1), // so that math.Exp does not overflow + ), + } + return &m, nil +} + +func (m *LinearlyInterpolatedMapping) Equals(other IndexMapping) bool { + o, ok := other.(*LinearlyInterpolatedMapping) + if !ok { + return false + } + tol := 1e-12 + return withinTolerance(m.gamma, o.gamma, tol) && withinTolerance(m.indexOffset, o.indexOffset, tol) +} + +func (m *LinearlyInterpolatedMapping) Index(value float64) int { + index := m.approximateLog(value)*m.multiplier + m.indexOffset + if index >= 0 { + return int(index) + } else { + return int(index) - 1 + } +} + +func (m *LinearlyInterpolatedMapping) Value(index int) float64 { + return m.LowerBound(index) * (1 + m.RelativeAccuracy()) +} + +func (m *LinearlyInterpolatedMapping) LowerBound(index int) float64 { + return m.approximateInverseLog((float64(index) - m.indexOffset) / m.multiplier) +} + +// Return an approximation of Math.log(x) / Math.log(2) +func (m *LinearlyInterpolatedMapping) approximateLog(x float64) float64 { + bits := math.Float64bits(x) + return getExponent(bits) + getSignificandPlusOne(bits) - 1 +} + +// The exact inverse of approximateLog. +func (m *LinearlyInterpolatedMapping) approximateInverseLog(x float64) float64 { + exponent := math.Floor(x) + significandPlusOne := x - exponent + 1 + return buildFloat64(int(exponent), significandPlusOne) +} + +func (m *LinearlyInterpolatedMapping) MinIndexableValue() float64 { + return m.minIndexableValue +} + +func (m *LinearlyInterpolatedMapping) MaxIndexableValue() float64 { + return m.maxIndexableValue +} + +func (m *LinearlyInterpolatedMapping) RelativeAccuracy() float64 { + return 1 - 2/(1+math.Exp(math.Log2(m.gamma))) +} + +// Generates a protobuf representation of this LinearlyInterpolatedMapping. +func (m *LinearlyInterpolatedMapping) ToProto() *sketchpb.IndexMapping { + return &sketchpb.IndexMapping{ + Gamma: m.gamma, + IndexOffset: m.indexOffset, + Interpolation: sketchpb.IndexMapping_LINEAR, + } +} + +func (m *LinearlyInterpolatedMapping) Encode(b *[]byte) { + enc.EncodeFlag(b, enc.FlagIndexMappingBaseLinear) + enc.EncodeFloat64LE(b, m.gamma) + enc.EncodeFloat64LE(b, m.indexOffset) +} + +func (m *LinearlyInterpolatedMapping) string() string { + var buffer bytes.Buffer + buffer.WriteString(fmt.Sprintf("gamma: %v, indexOffset: %v\n", m.gamma, m.indexOffset)) + return buffer.String() +} + +func withinTolerance(x, y, tolerance float64) bool { + if x == 0 || y == 0 { + return math.Abs(x) <= tolerance && math.Abs(y) <= tolerance + } else { + return math.Abs(x-y) <= tolerance*math.Max(math.Abs(x), math.Abs(y)) + } +} + +var _ IndexMapping = (*LinearlyInterpolatedMapping)(nil) diff --git a/vendor/github.com/DataDog/sketches-go/ddsketch/mapping/logarithmic_mapping.go b/vendor/github.com/DataDog/sketches-go/ddsketch/mapping/logarithmic_mapping.go new file mode 100644 index 000000000..474e74d93 --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/ddsketch/mapping/logarithmic_mapping.go @@ -0,0 +1,119 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +package mapping + +import ( + "bytes" + "errors" + "fmt" + "math" + + enc "github.com/DataDog/sketches-go/ddsketch/encoding" + "github.com/DataDog/sketches-go/ddsketch/pb/sketchpb" +) + +// LogarithmicMapping is an IndexMapping that is memory-optimal, that is to say +// that given a targeted relative accuracy, it requires the least number of +// indices to cover a given range of values. This is done by logarithmically +// mapping floating-point values to integers. +type LogarithmicMapping struct { + gamma float64 // base + indexOffset float64 + multiplier float64 // precomputed for performance + minIndexableValue float64 + maxIndexableValue float64 +} + +func NewLogarithmicMapping(relativeAccuracy float64) (*LogarithmicMapping, error) { + if relativeAccuracy <= 0 || relativeAccuracy >= 1 { + return nil, errors.New("The relative accuracy must be between 0 and 1.") + } + gamma := (1 + relativeAccuracy) / (1 - relativeAccuracy) // > 1 + m, _ := NewLogarithmicMappingWithGamma(gamma, 0) + return m, nil +} + +func NewLogarithmicMappingWithGamma(gamma, indexOffset float64) (*LogarithmicMapping, error) { + if gamma <= 1 { + return nil, errors.New("Gamma must be greater than 1.") + } + multiplier := 1 / math.Log(gamma) + m := &LogarithmicMapping{ + gamma: gamma, + indexOffset: indexOffset, + multiplier: multiplier, + minIndexableValue: math.Max( + math.Exp((math.MinInt32-indexOffset)/multiplier+1), // so that index >= MinInt32 + minNormalFloat64*gamma, + ), + maxIndexableValue: math.Min( + math.Exp((math.MaxInt32-indexOffset)/multiplier-1), // so that index <= MaxInt32 + math.Exp(expOverflow)/(2*gamma)*(gamma+1), // so that math.Exp does not overflow + ), + } + return m, nil +} + +func (m *LogarithmicMapping) Equals(other IndexMapping) bool { + o, ok := other.(*LogarithmicMapping) + if !ok { + return false + } + tol := 1e-12 + return withinTolerance(m.gamma, o.gamma, tol) && withinTolerance(m.indexOffset, o.indexOffset, tol) +} + +func (m *LogarithmicMapping) Index(value float64) int { + index := math.Log(value)*m.multiplier + m.indexOffset + if index >= 0 { + return int(index) + } else { + return int(index) - 1 // faster than Math.Floor + } +} + +func (m *LogarithmicMapping) Value(index int) float64 { + return m.LowerBound(index) * (1 + m.RelativeAccuracy()) +} + +func (m *LogarithmicMapping) LowerBound(index int) float64 { + return math.Exp((float64(index) - m.indexOffset) / m.multiplier) +} + +func (m *LogarithmicMapping) MinIndexableValue() float64 { + return m.minIndexableValue +} + +func (m *LogarithmicMapping) MaxIndexableValue() float64 { + return m.maxIndexableValue +} + +func (m *LogarithmicMapping) RelativeAccuracy() float64 { + return 1 - 2/(1+m.gamma) +} + +// Generates a protobuf representation of this LogarithicMapping. +func (m *LogarithmicMapping) ToProto() *sketchpb.IndexMapping { + return &sketchpb.IndexMapping{ + Gamma: m.gamma, + IndexOffset: m.indexOffset, + Interpolation: sketchpb.IndexMapping_NONE, + } +} + +func (m *LogarithmicMapping) Encode(b *[]byte) { + enc.EncodeFlag(b, enc.FlagIndexMappingBaseLogarithmic) + enc.EncodeFloat64LE(b, m.gamma) + enc.EncodeFloat64LE(b, m.indexOffset) +} + +func (m *LogarithmicMapping) string() string { + var buffer bytes.Buffer + buffer.WriteString(fmt.Sprintf("gamma: %v, indexOffset: %v\n", m.gamma, m.indexOffset)) + return buffer.String() +} + +var _ IndexMapping = (*LogarithmicMapping)(nil) diff --git a/vendor/github.com/DataDog/sketches-go/ddsketch/pb/sketchpb/ddsketch.pb.go b/vendor/github.com/DataDog/sketches-go/ddsketch/pb/sketchpb/ddsketch.pb.go new file mode 100644 index 000000000..9dbd6f293 --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/ddsketch/pb/sketchpb/ddsketch.pb.go @@ -0,0 +1,448 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache License 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.0 +// protoc v3.19.4 +// source: ddsketch.proto + +package sketchpb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type IndexMapping_Interpolation int32 + +const ( + IndexMapping_NONE IndexMapping_Interpolation = 0 + IndexMapping_LINEAR IndexMapping_Interpolation = 1 + IndexMapping_QUADRATIC IndexMapping_Interpolation = 2 + IndexMapping_CUBIC IndexMapping_Interpolation = 3 +) + +// Enum value maps for IndexMapping_Interpolation. +var ( + IndexMapping_Interpolation_name = map[int32]string{ + 0: "NONE", + 1: "LINEAR", + 2: "QUADRATIC", + 3: "CUBIC", + } + IndexMapping_Interpolation_value = map[string]int32{ + "NONE": 0, + "LINEAR": 1, + "QUADRATIC": 2, + "CUBIC": 3, + } +) + +func (x IndexMapping_Interpolation) Enum() *IndexMapping_Interpolation { + p := new(IndexMapping_Interpolation) + *p = x + return p +} + +func (x IndexMapping_Interpolation) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (IndexMapping_Interpolation) Descriptor() protoreflect.EnumDescriptor { + return file_ddsketch_proto_enumTypes[0].Descriptor() +} + +func (IndexMapping_Interpolation) Type() protoreflect.EnumType { + return &file_ddsketch_proto_enumTypes[0] +} + +func (x IndexMapping_Interpolation) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use IndexMapping_Interpolation.Descriptor instead. +func (IndexMapping_Interpolation) EnumDescriptor() ([]byte, []int) { + return file_ddsketch_proto_rawDescGZIP(), []int{1, 0} +} + +// A DDSketch is essentially a histogram that partitions the range of positive values into an infinite number of +// indexed bins whose size grows exponentially. It keeps track of the number of values (or possibly floating-point +// weights) added to each bin. Negative values are partitioned like positive values, symmetrically to zero. +// The value zero as well as its close neighborhood that would be mapped to extreme bin indexes is mapped to a specific +// counter. +type DDSketch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The mapping between positive values and the bin indexes they belong to. + Mapping *IndexMapping `protobuf:"bytes,1,opt,name=mapping,proto3" json:"mapping,omitempty"` + // The store for keeping track of positive values. + PositiveValues *Store `protobuf:"bytes,2,opt,name=positiveValues,proto3" json:"positiveValues,omitempty"` + // The store for keeping track of negative values. A negative value v is mapped using its positive opposite -v. + NegativeValues *Store `protobuf:"bytes,3,opt,name=negativeValues,proto3" json:"negativeValues,omitempty"` + // The count for the value zero and its close neighborhood (whose width depends on the mapping). + ZeroCount float64 `protobuf:"fixed64,4,opt,name=zeroCount,proto3" json:"zeroCount,omitempty"` +} + +func (x *DDSketch) Reset() { + *x = DDSketch{} + if protoimpl.UnsafeEnabled { + mi := &file_ddsketch_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DDSketch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DDSketch) ProtoMessage() {} + +func (x *DDSketch) ProtoReflect() protoreflect.Message { + mi := &file_ddsketch_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DDSketch.ProtoReflect.Descriptor instead. +func (*DDSketch) Descriptor() ([]byte, []int) { + return file_ddsketch_proto_rawDescGZIP(), []int{0} +} + +func (x *DDSketch) GetMapping() *IndexMapping { + if x != nil { + return x.Mapping + } + return nil +} + +func (x *DDSketch) GetPositiveValues() *Store { + if x != nil { + return x.PositiveValues + } + return nil +} + +func (x *DDSketch) GetNegativeValues() *Store { + if x != nil { + return x.NegativeValues + } + return nil +} + +func (x *DDSketch) GetZeroCount() float64 { + if x != nil { + return x.ZeroCount + } + return 0 +} + +// How to map positive values to the bins they belong to. +type IndexMapping struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The gamma parameter of the mapping, such that bin index that a value v belongs to is roughly equal to + // log(v)/log(gamma). + Gamma float64 `protobuf:"fixed64,1,opt,name=gamma,proto3" json:"gamma,omitempty"` + // An offset that can be used to shift all bin indexes. + IndexOffset float64 `protobuf:"fixed64,2,opt,name=indexOffset,proto3" json:"indexOffset,omitempty"` + // To speed up the computation of the index a value belongs to, the computation of the log may be approximated using + // the fact that the log to the base 2 of powers of 2 can be computed at a low cost from the binary representation of + // the input value. Other values can be approximated by interpolating between successive powers of 2 (linearly, + // quadratically or cubically). + // NONE means that the log is to be computed exactly (no interpolation). + Interpolation IndexMapping_Interpolation `protobuf:"varint,3,opt,name=interpolation,proto3,enum=IndexMapping_Interpolation" json:"interpolation,omitempty"` +} + +func (x *IndexMapping) Reset() { + *x = IndexMapping{} + if protoimpl.UnsafeEnabled { + mi := &file_ddsketch_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IndexMapping) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IndexMapping) ProtoMessage() {} + +func (x *IndexMapping) ProtoReflect() protoreflect.Message { + mi := &file_ddsketch_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IndexMapping.ProtoReflect.Descriptor instead. +func (*IndexMapping) Descriptor() ([]byte, []int) { + return file_ddsketch_proto_rawDescGZIP(), []int{1} +} + +func (x *IndexMapping) GetGamma() float64 { + if x != nil { + return x.Gamma + } + return 0 +} + +func (x *IndexMapping) GetIndexOffset() float64 { + if x != nil { + return x.IndexOffset + } + return 0 +} + +func (x *IndexMapping) GetInterpolation() IndexMapping_Interpolation { + if x != nil { + return x.Interpolation + } + return IndexMapping_NONE +} + +// A Store maps bin indexes to their respective counts. +// Counts can be encoded sparsely using binCounts, but also in a contiguous way using contiguousBinCounts and +// contiguousBinIndexOffset. Given that non-empty bins are in practice usually contiguous or close to one another, the +// latter contiguous encoding method is usually more efficient than the sparse one. +// Both encoding methods can be used conjointly. If a bin appears in both the sparse and the contiguous encodings, its +// count value is the sum of the counts in each encodings. +type Store struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The bin counts, encoded sparsely. + BinCounts map[int32]float64 `protobuf:"bytes,1,rep,name=binCounts,proto3" json:"binCounts,omitempty" protobuf_key:"zigzag32,1,opt,name=key,proto3" protobuf_val:"fixed64,2,opt,name=value,proto3"` + // The bin counts, encoded contiguously. The values of contiguousBinCounts are the counts for the bins of indexes + // o, o+1, o+2, etc., where o is contiguousBinIndexOffset. + ContiguousBinCounts []float64 `protobuf:"fixed64,2,rep,packed,name=contiguousBinCounts,proto3" json:"contiguousBinCounts,omitempty"` + ContiguousBinIndexOffset int32 `protobuf:"zigzag32,3,opt,name=contiguousBinIndexOffset,proto3" json:"contiguousBinIndexOffset,omitempty"` +} + +func (x *Store) Reset() { + *x = Store{} + if protoimpl.UnsafeEnabled { + mi := &file_ddsketch_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Store) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Store) ProtoMessage() {} + +func (x *Store) ProtoReflect() protoreflect.Message { + mi := &file_ddsketch_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Store.ProtoReflect.Descriptor instead. +func (*Store) Descriptor() ([]byte, []int) { + return file_ddsketch_proto_rawDescGZIP(), []int{2} +} + +func (x *Store) GetBinCounts() map[int32]float64 { + if x != nil { + return x.BinCounts + } + return nil +} + +func (x *Store) GetContiguousBinCounts() []float64 { + if x != nil { + return x.ContiguousBinCounts + } + return nil +} + +func (x *Store) GetContiguousBinIndexOffset() int32 { + if x != nil { + return x.ContiguousBinIndexOffset + } + return 0 +} + +var File_ddsketch_proto protoreflect.FileDescriptor + +var file_ddsketch_proto_rawDesc = []byte{ + 0x0a, 0x0e, 0x64, 0x64, 0x73, 0x6b, 0x65, 0x74, 0x63, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0xb1, 0x01, 0x0a, 0x08, 0x44, 0x44, 0x53, 0x6b, 0x65, 0x74, 0x63, 0x68, 0x12, 0x27, 0x0a, + 0x07, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x6d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x2e, 0x0a, 0x0e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x76, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x06, + 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x0e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x0e, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x06, + 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x0e, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x7a, 0x65, 0x72, 0x6f, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x7a, 0x65, 0x72, 0x6f, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xca, 0x01, 0x0a, 0x0c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4d, 0x61, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x61, 0x6d, 0x6d, 0x61, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x67, 0x61, 0x6d, 0x6d, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, + 0x52, 0x0b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x41, 0x0a, + 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4d, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x3f, 0x0a, 0x0d, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4c, + 0x49, 0x4e, 0x45, 0x41, 0x52, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x51, 0x55, 0x41, 0x44, 0x52, + 0x41, 0x54, 0x49, 0x43, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x55, 0x42, 0x49, 0x43, 0x10, + 0x03, 0x22, 0xec, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x33, 0x0a, 0x09, 0x62, + 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x42, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x62, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, + 0x12, 0x34, 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x67, 0x75, 0x6f, 0x75, 0x73, 0x42, 0x69, + 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x01, 0x42, 0x02, 0x10, + 0x01, 0x52, 0x13, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x67, 0x75, 0x6f, 0x75, 0x73, 0x42, 0x69, 0x6e, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x3a, 0x0a, 0x18, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x67, + 0x75, 0x6f, 0x75, 0x73, 0x42, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x18, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x67, + 0x75, 0x6f, 0x75, 0x73, 0x42, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x1a, 0x3c, 0x0a, 0x0e, 0x42, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x11, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, + 0x61, 0x74, 0x61, 0x44, 0x6f, 0x67, 0x2f, 0x73, 0x6b, 0x65, 0x74, 0x63, 0x68, 0x65, 0x73, 0x2d, + 0x67, 0x6f, 0x2f, 0x64, 0x64, 0x73, 0x6b, 0x65, 0x74, 0x63, 0x68, 0x2f, 0x70, 0x62, 0x2f, 0x73, + 0x6b, 0x65, 0x74, 0x63, 0x68, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_ddsketch_proto_rawDescOnce sync.Once + file_ddsketch_proto_rawDescData = file_ddsketch_proto_rawDesc +) + +func file_ddsketch_proto_rawDescGZIP() []byte { + file_ddsketch_proto_rawDescOnce.Do(func() { + file_ddsketch_proto_rawDescData = protoimpl.X.CompressGZIP(file_ddsketch_proto_rawDescData) + }) + return file_ddsketch_proto_rawDescData +} + +var file_ddsketch_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_ddsketch_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_ddsketch_proto_goTypes = []interface{}{ + (IndexMapping_Interpolation)(0), // 0: IndexMapping.Interpolation + (*DDSketch)(nil), // 1: DDSketch + (*IndexMapping)(nil), // 2: IndexMapping + (*Store)(nil), // 3: Store + nil, // 4: Store.BinCountsEntry +} +var file_ddsketch_proto_depIdxs = []int32{ + 2, // 0: DDSketch.mapping:type_name -> IndexMapping + 3, // 1: DDSketch.positiveValues:type_name -> Store + 3, // 2: DDSketch.negativeValues:type_name -> Store + 0, // 3: IndexMapping.interpolation:type_name -> IndexMapping.Interpolation + 4, // 4: Store.binCounts:type_name -> Store.BinCountsEntry + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_ddsketch_proto_init() } +func file_ddsketch_proto_init() { + if File_ddsketch_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_ddsketch_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DDSketch); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ddsketch_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IndexMapping); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ddsketch_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Store); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_ddsketch_proto_rawDesc, + NumEnums: 1, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_ddsketch_proto_goTypes, + DependencyIndexes: file_ddsketch_proto_depIdxs, + EnumInfos: file_ddsketch_proto_enumTypes, + MessageInfos: file_ddsketch_proto_msgTypes, + }.Build() + File_ddsketch_proto = out.File + file_ddsketch_proto_rawDesc = nil + file_ddsketch_proto_goTypes = nil + file_ddsketch_proto_depIdxs = nil +} diff --git a/vendor/github.com/DataDog/sketches-go/ddsketch/stat/summary.go b/vendor/github.com/DataDog/sketches-go/ddsketch/stat/summary.go new file mode 100644 index 000000000..5d56f3944 --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/ddsketch/stat/summary.go @@ -0,0 +1,171 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +package stat + +import ( + "fmt" + "math" +) + +// SummaryStatistics keeps track of the count, the sum, the min and the max of +// recorded values. We use a compensated sum to avoid accumulating rounding +// errors (see https://en.wikipedia.org/wiki/Kahan_summation_algorithm). +type SummaryStatistics struct { + count float64 + sum float64 + sumCompensation float64 + simpleSum float64 + min float64 + max float64 +} + +func NewSummaryStatistics() *SummaryStatistics { + return &SummaryStatistics{ + count: 0, + sum: 0, + sumCompensation: 0, + simpleSum: 0, + min: math.Inf(1), + max: math.Inf(-1), + } +} + +// NewSummaryStatisticsFromData constructs SummaryStatistics from the provided data. +func NewSummaryStatisticsFromData(count, sum, min, max float64) (*SummaryStatistics, error) { + if !(count >= 0) { + return nil, fmt.Errorf("count (%g) must be positive or zero", count) + } + if count > 0 && min > max { + return nil, fmt.Errorf("min (%g) cannot be greater than max (%g) if count (%g) is positive", min, max, count) + } + if count == 0 && (min != math.Inf(1) || max != math.Inf(-1)) { + return nil, fmt.Errorf("empty summary statistics must have min (%g) and max (%g) equal to positive and negative infinities respectively", min, max) + } + return &SummaryStatistics{ + count: count, + sum: sum, + sumCompensation: 0, + simpleSum: sum, + min: min, + max: max, + }, nil +} + +func (s *SummaryStatistics) Count() float64 { + return s.count +} + +func (s *SummaryStatistics) Sum() float64 { + // Better error bounds to add both terms as the final sum + tmp := s.sum + s.sumCompensation + if math.IsNaN(tmp) && math.IsInf(s.simpleSum, 0) { + // If the compensated sum is spuriously NaN from accumulating one or more same-signed infinite + // values, return the correctly-signed infinity stored in simpleSum. + return s.simpleSum + } else { + return tmp + } +} + +func (s *SummaryStatistics) Min() float64 { + return s.min +} + +func (s *SummaryStatistics) Max() float64 { + return s.max +} + +func (s *SummaryStatistics) Add(value, count float64) { + s.AddToCount(count) + s.AddToSum(value * count) + if value < s.min { + s.min = value + } + if value > s.max { + s.max = value + } +} + +func (s *SummaryStatistics) AddToCount(addend float64) { + s.count += addend +} + +func (s *SummaryStatistics) AddToSum(addend float64) { + s.sumWithCompensation(addend) + s.simpleSum += addend +} + +func (s *SummaryStatistics) MergeWith(o *SummaryStatistics) { + s.count += o.count + s.sumWithCompensation(o.sum) + s.sumWithCompensation(o.sumCompensation) + s.simpleSum += o.simpleSum + if o.min < s.min { + s.min = o.min + } + if o.max > s.max { + s.max = o.max + } +} + +func (s *SummaryStatistics) sumWithCompensation(value float64) { + tmp := value - s.sumCompensation + velvel := s.sum + tmp // little wolf of rounding error + s.sumCompensation = velvel - s.sum - tmp + s.sum = velvel +} + +// Reweight adjusts the statistics so that they are equal to what they would +// have been if AddWithCount had been called with counts multiplied by factor. +func (s *SummaryStatistics) Reweight(factor float64) { + s.count *= factor + s.sum *= factor + s.sumCompensation *= factor + s.simpleSum *= factor + if factor == 0 { + s.min = math.Inf(1) + s.max = math.Inf(-1) + } +} + +// Rescale adjusts the statistics so that they are equal to what they would have +// been if AddWithCount had been called with values multiplied by factor. +func (s *SummaryStatistics) Rescale(factor float64) { + s.sum *= factor + s.sumCompensation *= factor + s.simpleSum *= factor + if factor > 0 { + s.min *= factor + s.max *= factor + } else if factor < 0 { + tmp := s.max * factor + s.max = s.min * factor + s.min = tmp + } else if s.count != 0 { + s.min = 0 + s.max = 0 + } +} + +func (s *SummaryStatistics) Clear() { + s.count = 0 + s.sum = 0 + s.sumCompensation = 0 + s.simpleSum = 0 + s.min = math.Inf(1) + s.max = math.Inf(-1) +} + +func (s *SummaryStatistics) Copy() *SummaryStatistics { + return &SummaryStatistics{ + count: s.count, + sum: s.sum, + sumCompensation: s.sumCompensation, + simpleSum: s.simpleSum, + min: s.min, + max: s.max, + } +} diff --git a/vendor/github.com/DataDog/sketches-go/ddsketch/store/bin.go b/vendor/github.com/DataDog/sketches-go/ddsketch/store/bin.go new file mode 100644 index 000000000..19843ba9e --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/ddsketch/store/bin.go @@ -0,0 +1,28 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +package store + +import "errors" + +type Bin struct { + index int + count float64 +} + +func NewBin(index int, count float64) (*Bin, error) { + if count < 0 { + return nil, errors.New("The count cannot be negative") + } + return &Bin{index: index, count: count}, nil +} + +func (b Bin) Index() int { + return b.index +} + +func (b Bin) Count() float64 { + return b.count +} diff --git a/vendor/github.com/DataDog/sketches-go/ddsketch/store/buffered_paginated.go b/vendor/github.com/DataDog/sketches-go/ddsketch/store/buffered_paginated.go new file mode 100644 index 000000000..11f43107d --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/ddsketch/store/buffered_paginated.go @@ -0,0 +1,667 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +package store + +import ( + "errors" + "sort" + + enc "github.com/DataDog/sketches-go/ddsketch/encoding" + "github.com/DataDog/sketches-go/ddsketch/pb/sketchpb" +) + +const ( + ptrSize = 32 << (^uintptr(0) >> 63) + intSize = 32 << (^uint(0) >> 63) + float64size = 64 + bufferEntrySize = intSize + countSize = float64size + + defaultPageLenLog2 = 5 // pageLen = 32 +) + +// BufferedPaginatedStore allocates storage for counts in aligned fixed-size +// pages, themselves stored in a dynamically-sized slice. A page encodes the +// counts for a contiguous range of indexes, and two pages that are contiguous +// in the slice encode ranges that are contiguous. In addition, input indexes +// that are added to the store with a count equal to 1 can be stored in a +// buffer. +// The store favors using the buffer and only creates pages when the memory size +// of the page is no greater than the memory space that is needed to keep in the +// buffer the indexes that could otherwise be encoded in that page. That means +// that some indexes may stay indefinitely in the buffer if, to be removed from +// the buffer, they would create a page that is almost empty. The process that +// transfers indexes from the buffer to pages is called compaction. +// This store never collapses or merges bins, therefore, it does not introduce +// any error in itself. In particular, MinIndex(), MaxIndex(), Bins() and +// KeyAtRank() return exact results. +// There is no upper bound on the memory size that this store needs to encode +// input indexes, and some input data distributions may make it reach large +// sizes. However, thanks to the buffer and the fact that only required pages +// are allocated, it can be much more space efficient than alternative stores, +// especially dense stores, in various situations, including when only few +// indexes are added (with their counts equal to 1), when the input data has a +// few outliers or when the input data distribution is multimodal. +type BufferedPaginatedStore struct { + buffer []int // FIXME: in practice, int32 (even int16, depending on the accuracy parameter) is enough + bufferCompactionTriggerLen int // compaction happens only after this buffer length is reached + + pages [][]float64 // len == cap, the slice is always used to its maximum capacity + minPageIndex int // minPageIndex == maxInt iff pages are unused (they may still be allocated) + pageLenLog2 int + pageLenMask int +} + +func NewBufferedPaginatedStore() *BufferedPaginatedStore { + initialBufferCapacity := 4 + pageLenLog2 := defaultPageLenLog2 + pageLen := 1 << pageLenLog2 + + return &BufferedPaginatedStore{ + buffer: make([]int, 0, initialBufferCapacity), + bufferCompactionTriggerLen: 2 * pageLen, + pages: nil, + minPageIndex: maxInt, + pageLenLog2: pageLenLog2, + pageLenMask: pageLen - 1, + } +} + +// pageIndex returns the page number the given index falls on. +func (s *BufferedPaginatedStore) pageIndex(index int) int { + return index >> s.pageLenLog2 +} + +// lineIndex returns the line number within a page that the given index falls on. +func (s *BufferedPaginatedStore) lineIndex(index int) int { + return index & s.pageLenMask +} + +// index returns the store-level index for a given page number and a line within that page. +func (s *BufferedPaginatedStore) index(pageIndex, lineIndex int) int { + return pageIndex<= s.minPageIndex && pageIndex < s.minPageIndex+len(s.pages) { + // No need to extend s.pages. + page := &s.pages[pageIndex-s.minPageIndex] + if ensureExists && len(*page) == 0 { + *page = append(*page, make([]float64, pageLen)...) + } + return *page + } + + if !ensureExists { + return nil + } + + if pageIndex < s.minPageIndex { + if s.minPageIndex == maxInt { + if len(s.pages) == 0 { + s.pages = append(s.pages, make([][]float64, s.newPagesLen(1))...) + } + s.minPageIndex = pageIndex - len(s.pages)/2 + } else { + // Extends s.pages left. + newLen := s.newPagesLen(s.minPageIndex - pageIndex + 1 + len(s.pages)) + addedLen := newLen - len(s.pages) + s.pages = append(s.pages, make([][]float64, addedLen)...) + copy(s.pages[addedLen:], s.pages) + for i := 0; i < addedLen; i++ { + s.pages[i] = nil + } + s.minPageIndex -= addedLen + } + } else { + // Extends s.pages right. + s.pages = append(s.pages, make([][]float64, s.newPagesLen(pageIndex-s.minPageIndex+1)-len(s.pages))...) + } + + page := &s.pages[pageIndex-s.minPageIndex] + if len(*page) == 0 { + *page = append(*page, make([]float64, pageLen)...) + } + return *page +} + +func (s *BufferedPaginatedStore) newPagesLen(required int) int { + // Grow in size by multiples of 64 bytes + pageGrowthIncrement := 64 * 8 / ptrSize + return (required + pageGrowthIncrement - 1) & -pageGrowthIncrement +} + +// compact transfers indexes from the buffer to the pages. It only creates new +// pages if they can encode enough buffered indexes so that it frees more space +// in the buffer than the new page takes. +func (s *BufferedPaginatedStore) compact() { + pageLen := 1 << s.pageLenLog2 + + s.sortBuffer() + + for bufferPos := 0; bufferPos < len(s.buffer); { + bufferPageStart := bufferPos + pageIndex := s.pageIndex(s.buffer[bufferPageStart]) + bufferPos++ + for bufferPos < len(s.buffer) && s.pageIndex(s.buffer[bufferPos]) == pageIndex { + bufferPos++ + } + bufferPageEnd := bufferPos + + // We avoid creating a new page if it would take more memory space than + // what we would free in the buffer. Note that even when the page itself + // takes less memory space than the buffered indexes that can be encoded + // in the page, because we may have to extend s.pages, the store may end + // up larger. However, for the sake of simplicity, we ignore the length + // of s.pages. + ensureExists := (bufferPageEnd-bufferPageStart)*bufferEntrySize >= pageLen*float64size + newPage := s.page(pageIndex, ensureExists) + if len(newPage) > 0 { + for _, index := range s.buffer[bufferPageStart:bufferPageEnd] { + newPage[s.lineIndex(index)]++ + } + copy(s.buffer[bufferPageStart:], s.buffer[bufferPageEnd:]) + s.buffer = s.buffer[:len(s.buffer)+bufferPageStart-bufferPageEnd] + bufferPos = bufferPageStart + } + } + + s.bufferCompactionTriggerLen = len(s.buffer) + pageLen +} + +func (s *BufferedPaginatedStore) sortBuffer() { + sort.Slice(s.buffer, func(i, j int) bool { return s.buffer[i] < s.buffer[j] }) +} + +func (s *BufferedPaginatedStore) Add(index int) { + pageIndex := s.pageIndex(index) + if pageIndex >= s.minPageIndex && pageIndex < s.minPageIndex+len(s.pages) { + page := s.pages[pageIndex-s.minPageIndex] + if len(page) > 0 { + page[s.lineIndex(index)]++ + return + } + } + + // The page does not exist, use the buffer. + if len(s.buffer) == cap(s.buffer) && len(s.buffer) >= s.bufferCompactionTriggerLen { + s.compact() + } + + s.buffer = append(s.buffer, index) +} + +func (s *BufferedPaginatedStore) AddBin(bin Bin) { + s.AddWithCount(bin.Index(), bin.Count()) +} + +func (s *BufferedPaginatedStore) AddWithCount(index int, count float64) { + if count == 0 { + return + } else if count == 1 { + s.Add(index) + } else { + s.page(s.pageIndex(index), true)[s.lineIndex(index)] += count + } +} + +func (s *BufferedPaginatedStore) IsEmpty() bool { + if len(s.buffer) > 0 { + return false + } + for _, page := range s.pages { + for _, count := range page { + if count > 0 { + return false + } + } + } + return true +} + +func (s *BufferedPaginatedStore) TotalCount() float64 { + totalCount := float64(len(s.buffer)) + for _, page := range s.pages { + for _, count := range page { + totalCount += count + } + } + return totalCount +} + +func (s *BufferedPaginatedStore) MinIndex() (int, error) { + isEmpty := true + + // Iterate over the buffer. + var minIndex int + for _, index := range s.buffer { + if isEmpty || index < minIndex { + isEmpty = false + minIndex = index + } + } + + // Iterate over the pages. + for pageIndex := s.minPageIndex; pageIndex < s.minPageIndex+len(s.pages) && (isEmpty || pageIndex <= s.pageIndex(minIndex)); pageIndex++ { + page := s.pages[pageIndex-s.minPageIndex] + if len(page) == 0 { + continue + } + + var lineIndexRangeEnd int + if !isEmpty && pageIndex == s.pageIndex(minIndex) { + lineIndexRangeEnd = s.lineIndex(minIndex) + } else { + lineIndexRangeEnd = 1 << s.pageLenLog2 + } + + for lineIndex := 0; lineIndex < lineIndexRangeEnd; lineIndex++ { + if page[lineIndex] > 0 { + return s.index(pageIndex, lineIndex), nil + } + } + } + + if isEmpty { + return 0, errUndefinedMinIndex + } else { + return minIndex, nil + } +} + +func (s *BufferedPaginatedStore) MaxIndex() (int, error) { + isEmpty := true + + // Iterate over the buffer. + var maxIndex int + for _, index := range s.buffer { + if isEmpty || index > maxIndex { + isEmpty = false + maxIndex = index + } + } + + // Iterate over the pages. + for pageIndex := s.minPageIndex + len(s.pages) - 1; pageIndex >= s.minPageIndex && (isEmpty || pageIndex >= s.pageIndex(maxIndex)); pageIndex-- { + page := s.pages[pageIndex-s.minPageIndex] + if len(page) == 0 { + continue + } + + var lineIndexRangeStart int + if !isEmpty && pageIndex == s.pageIndex(maxIndex) { + lineIndexRangeStart = s.lineIndex(maxIndex) + } else { + lineIndexRangeStart = 0 + } + + for lineIndex := len(page) - 1; lineIndex >= lineIndexRangeStart; lineIndex-- { + if page[lineIndex] > 0 { + return s.index(pageIndex, lineIndex), nil + } + } + } + + if isEmpty { + return 0, errUndefinedMaxIndex + } else { + return maxIndex, nil + } +} + +func (s *BufferedPaginatedStore) KeyAtRank(rank float64) int { + if rank < 0 { + rank = 0 + } + key, err := s.minIndexWithCumulCount(func(cumulCount float64) bool { + return cumulCount > rank + }) + + if err != nil { + maxIndex, err := s.MaxIndex() + if err == nil { + return maxIndex + } else { + // FIXME: make Store's KeyAtRank consistent with MinIndex and MaxIndex + return 0 + } + } + return key +} + +// minIndexWithCumulCount returns the minimum index whose cumulative count (that +// is, the sum of the counts associated with the indexes less than or equal to +// the index) verifies the predicate. +func (s *BufferedPaginatedStore) minIndexWithCumulCount(predicate func(float64) bool) (int, error) { + s.sortBuffer() + cumulCount := float64(0) + + // Iterate over the pages and the buffer simultaneously. + bufferPos := 0 + for pageOffset, page := range s.pages { + for lineIndex, count := range page { + index := s.index(s.minPageIndex+pageOffset, lineIndex) + + // Iterate over the buffer until index is reached. + for ; bufferPos < len(s.buffer) && s.buffer[bufferPos] < index; bufferPos++ { + cumulCount++ + if predicate(cumulCount) { + return s.buffer[bufferPos], nil + } + } + cumulCount += count + if predicate(cumulCount) { + return index, nil + } + } + } + + // Iterate over the rest of the buffer + for ; bufferPos < len(s.buffer); bufferPos++ { + cumulCount++ + if predicate(cumulCount) { + return s.buffer[bufferPos], nil + } + } + + return 0, errors.New("the predicate on the cumulative count is never verified") +} + +func (s *BufferedPaginatedStore) MergeWith(other Store) { + o, ok := other.(*BufferedPaginatedStore) + if ok && s.pageLenLog2 == o.pageLenLog2 { + // Merge pages. + for oPageOffset, oPage := range o.pages { + if len(oPage) == 0 { + continue + } + oPageIndex := o.minPageIndex + oPageOffset + page := s.page(oPageIndex, true) + for i, oCount := range oPage { + page[i] += oCount + } + } + + // Merge buffers. + for _, index := range o.buffer { + s.Add(index) + } + } else { + // Fallback merging. + other.ForEach(func(index int, count float64) (stop bool) { + s.AddWithCount(index, count) + return false + }) + } +} + +func (s *BufferedPaginatedStore) MergeWithProto(pb *sketchpb.Store) { + for index, count := range pb.BinCounts { + s.AddWithCount(int(index), count) + } + for indexOffset, count := range pb.ContiguousBinCounts { + s.AddWithCount(int(pb.ContiguousBinIndexOffset)+indexOffset, count) + } +} + +func (s *BufferedPaginatedStore) Bins() <-chan Bin { + s.sortBuffer() + ch := make(chan Bin) + go func() { + defer close(ch) + bufferPos := 0 + + // Iterate over the pages and the buffer simultaneously. + for pageOffset, page := range s.pages { + for lineIndex, count := range page { + if count == 0 { + continue + } + + index := s.index(s.minPageIndex+pageOffset, lineIndex) + + // Iterate over the buffer until index is reached. + var indexBufferStartPos int + for { + indexBufferStartPos = bufferPos + if indexBufferStartPos >= len(s.buffer) || s.buffer[indexBufferStartPos] > index { + break + } + bufferPos++ + for bufferPos < len(s.buffer) && s.buffer[bufferPos] == s.buffer[indexBufferStartPos] { + bufferPos++ + } + if s.buffer[indexBufferStartPos] == index { + break + } + ch <- Bin{index: s.buffer[indexBufferStartPos], count: float64(bufferPos - indexBufferStartPos)} + } + ch <- Bin{index: index, count: count + float64(bufferPos-indexBufferStartPos)} + } + } + + // Iterate over the rest of the buffer. + for bufferPos < len(s.buffer) { + indexBufferStartPos := bufferPos + bufferPos++ + for bufferPos < len(s.buffer) && s.buffer[bufferPos] == s.buffer[indexBufferStartPos] { + bufferPos++ + } + bin := Bin{index: s.buffer[indexBufferStartPos], count: float64(bufferPos - indexBufferStartPos)} + ch <- bin + } + }() + return ch +} + +func (s *BufferedPaginatedStore) ForEach(f func(index int, count float64) (stop bool)) { + s.sortBuffer() + bufferPos := 0 + + // Iterate over the pages and the buffer simultaneously. + for pageOffset, page := range s.pages { + for lineIndex, count := range page { + if count == 0 { + continue + } + + index := s.index(s.minPageIndex+pageOffset, lineIndex) + + // Iterate over the buffer until index is reached. + var indexBufferStartPos int + for { + indexBufferStartPos = bufferPos + if indexBufferStartPos >= len(s.buffer) || s.buffer[indexBufferStartPos] > index { + break + } + bufferPos++ + for bufferPos < len(s.buffer) && s.buffer[bufferPos] == s.buffer[indexBufferStartPos] { + bufferPos++ + } + if s.buffer[indexBufferStartPos] == index { + break + } + if f(s.buffer[indexBufferStartPos], float64(bufferPos-indexBufferStartPos)) { + return + } + } + if f(index, count+float64(bufferPos-indexBufferStartPos)) { + return + } + } + } + + // Iterate over the rest of the buffer. + for bufferPos < len(s.buffer) { + indexBufferStartPos := bufferPos + bufferPos++ + for bufferPos < len(s.buffer) && s.buffer[bufferPos] == s.buffer[indexBufferStartPos] { + bufferPos++ + } + if f(s.buffer[indexBufferStartPos], float64(bufferPos-indexBufferStartPos)) { + return + } + } +} + +func (s *BufferedPaginatedStore) Copy() Store { + bufferCopy := make([]int, len(s.buffer)) + copy(bufferCopy, s.buffer) + pagesCopy := make([][]float64, len(s.pages)) + for i, page := range s.pages { + if len(page) > 0 { + pageCopy := make([]float64, len(page)) + copy(pageCopy, page) + pagesCopy[i] = pageCopy + } + } + return &BufferedPaginatedStore{ + buffer: bufferCopy, + bufferCompactionTriggerLen: s.bufferCompactionTriggerLen, + pages: pagesCopy, + minPageIndex: s.minPageIndex, + pageLenLog2: s.pageLenLog2, + pageLenMask: s.pageLenMask, + } +} + +func (s *BufferedPaginatedStore) Clear() { + s.buffer = s.buffer[:0] + for i := range s.pages { + s.pages[i] = s.pages[i][:0] + } + s.minPageIndex = maxInt +} + +func (s *BufferedPaginatedStore) ToProto() *sketchpb.Store { + if s.IsEmpty() { + return &sketchpb.Store{} + } + // FIXME: add heuristic to use contiguousBinCounts when cheaper. + binCounts := make(map[int32]float64) + s.ForEach(func(index int, count float64) (stop bool) { + binCounts[int32(index)] = count + return false + }) + return &sketchpb.Store{ + BinCounts: binCounts, + } +} + +func (s *BufferedPaginatedStore) Reweight(w float64) error { + if w <= 0 { + return errors.New("can't reweight by a negative factor") + } + if w == 1 { + return nil + } + buffer := s.buffer + s.buffer = s.buffer[:0] + for _, p := range s.pages { + for i := range p { + p[i] *= w + } + } + for _, index := range buffer { + s.AddWithCount(index, w) + } + return nil +} + +func (s *BufferedPaginatedStore) Encode(b *[]byte, t enc.FlagType) { + s.compact() + if len(s.buffer) > 0 { + enc.EncodeFlag(b, enc.NewFlag(t, enc.BinEncodingIndexDeltas)) + enc.EncodeUvarint64(b, uint64(len(s.buffer))) + previousIndex := 0 + for _, index := range s.buffer { + enc.EncodeVarint64(b, int64(index-previousIndex)) + previousIndex = index + } + } + + for pageOffset, page := range s.pages { + if len(page) > 0 { + enc.EncodeFlag(b, enc.NewFlag(t, enc.BinEncodingContiguousCounts)) + enc.EncodeUvarint64(b, uint64(len(page))) + enc.EncodeVarint64(b, int64(s.index(s.minPageIndex+pageOffset, 0))) + enc.EncodeVarint64(b, 1) + for _, count := range page { + enc.EncodeVarfloat64(b, count) + } + } + } +} + +func (s *BufferedPaginatedStore) DecodeAndMergeWith(b *[]byte, encodingMode enc.SubFlag) error { + switch encodingMode { + + case enc.BinEncodingIndexDeltas: + numBins, err := enc.DecodeUvarint64(b) + if err != nil { + return err + } + remaining := int(numBins) + index := int64(0) + // Process indexes in batches to avoid checking after each insertion + // whether compaction should happen. + for { + batchSize := min(remaining, max(cap(s.buffer), s.bufferCompactionTriggerLen)-len(s.buffer)) + for i := 0; i < batchSize; i++ { + indexDelta, err := enc.DecodeVarint64(b) + if err != nil { + return err + } + index += indexDelta + s.buffer = append(s.buffer, int(index)) + } + remaining -= batchSize + if remaining == 0 { + return nil + } + s.compact() + } + + case enc.BinEncodingContiguousCounts: + numBins, err := enc.DecodeUvarint64(b) + if err != nil { + return err + } + indexOffset, err := enc.DecodeVarint64(b) + if err != nil { + return err + } + indexDelta, err := enc.DecodeVarint64(b) + if err != nil { + return err + } + pageLen := 1 << s.pageLenLog2 + for i := uint64(0); i < numBins; { + page := s.page(s.pageIndex(int(indexOffset)), true) + lineIndex := s.lineIndex(int(indexOffset)) + for lineIndex >= 0 && lineIndex < pageLen && i < numBins { + count, err := enc.DecodeVarfloat64(b) + if err != nil { + return err + } + page[lineIndex] += count + lineIndex += int(indexDelta) + indexOffset += indexDelta + i++ + } + } + return nil + + default: + return DecodeAndMergeWith(s, b, encodingMode) + } +} + +var _ Store = (*BufferedPaginatedStore)(nil) diff --git a/vendor/github.com/DataDog/sketches-go/ddsketch/store/collapsing_highest_dense_store.go b/vendor/github.com/DataDog/sketches-go/ddsketch/store/collapsing_highest_dense_store.go new file mode 100644 index 000000000..2a431a176 --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/ddsketch/store/collapsing_highest_dense_store.go @@ -0,0 +1,188 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +package store + +import ( + "math" + + enc "github.com/DataDog/sketches-go/ddsketch/encoding" +) + +type CollapsingHighestDenseStore struct { + DenseStore + maxNumBins int + isCollapsed bool +} + +func NewCollapsingHighestDenseStore(maxNumBins int) *CollapsingHighestDenseStore { + return &CollapsingHighestDenseStore{ + DenseStore: DenseStore{minIndex: math.MaxInt32, maxIndex: math.MinInt32}, + maxNumBins: maxNumBins, + isCollapsed: false, + } +} + +func (s *CollapsingHighestDenseStore) Add(index int) { + s.AddWithCount(index, float64(1)) +} + +func (s *CollapsingHighestDenseStore) AddBin(bin Bin) { + index := bin.Index() + count := bin.Count() + if count == 0 { + return + } + s.AddWithCount(index, count) +} + +func (s *CollapsingHighestDenseStore) AddWithCount(index int, count float64) { + if count == 0 { + return + } + arrayIndex := s.normalize(index) + s.bins[arrayIndex] += count + s.count += count +} + +// Normalize the store, if necessary, so that the counter of the specified index can be updated. +func (s *CollapsingHighestDenseStore) normalize(index int) int { + if index > s.maxIndex { + if s.isCollapsed { + return len(s.bins) - 1 + } else { + s.extendRange(index, index) + if s.isCollapsed { + return len(s.bins) - 1 + } + } + } else if index < s.minIndex { + s.extendRange(index, index) + } + return index - s.offset +} + +func (s *CollapsingHighestDenseStore) getNewLength(newMinIndex, newMaxIndex int) int { + return min(s.DenseStore.getNewLength(newMinIndex, newMaxIndex), s.maxNumBins) +} + +func (s *CollapsingHighestDenseStore) extendRange(newMinIndex, newMaxIndex int) { + newMinIndex = min(newMinIndex, s.minIndex) + newMaxIndex = max(newMaxIndex, s.maxIndex) + if s.IsEmpty() { + initialLength := s.getNewLength(newMinIndex, newMaxIndex) + s.bins = append(s.bins, make([]float64, initialLength)...) + s.offset = newMinIndex + s.minIndex = newMinIndex + s.maxIndex = newMaxIndex + s.adjust(newMinIndex, newMaxIndex) + } else if newMinIndex >= s.offset && newMaxIndex < s.offset+len(s.bins) { + s.minIndex = newMinIndex + s.maxIndex = newMaxIndex + } else { + // To avoid shifting too often when nearing the capacity of the array, + // we may grow it before we actually reach the capacity. + newLength := s.getNewLength(newMinIndex, newMaxIndex) + if newLength > len(s.bins) { + s.bins = append(s.bins, make([]float64, newLength-len(s.bins))...) + } + s.adjust(newMinIndex, newMaxIndex) + } +} + +// Adjust bins, offset, minIndex and maxIndex, without resizing the bins slice in order to make it fit the +// specified range. +func (s *CollapsingHighestDenseStore) adjust(newMinIndex, newMaxIndex int) { + if newMaxIndex-newMinIndex+1 > len(s.bins) { + // The range of indices is too wide, buckets of lowest indices need to be collapsed. + newMaxIndex = newMinIndex + len(s.bins) - 1 + if newMaxIndex <= s.minIndex { + // There will be only one non-empty bucket. + s.bins = make([]float64, len(s.bins)) + s.offset = newMinIndex + s.maxIndex = newMaxIndex + s.bins[len(s.bins)-1] = s.count + } else { + shift := s.offset - newMinIndex + if shift > 0 { + // Collapse the buckets. + n := float64(0) + for i := newMaxIndex + 1; i <= s.maxIndex; i++ { + n += s.bins[i-s.offset] + } + s.resetBins(newMaxIndex+1, s.maxIndex) + s.bins[newMaxIndex-s.offset] += n + s.maxIndex = newMaxIndex + // Shift the buckets to make room for newMinIndex. + s.shiftCounts(shift) + } else { + // Shift the buckets to make room for newMaxIndex. + s.shiftCounts(shift) + s.maxIndex = newMaxIndex + } + } + s.minIndex = newMinIndex + s.isCollapsed = true + } else { + s.centerCounts(newMinIndex, newMaxIndex) + } +} + +func (s *CollapsingHighestDenseStore) MergeWith(other Store) { + if other.IsEmpty() { + return + } + o, ok := other.(*CollapsingHighestDenseStore) + if !ok { + other.ForEach(func(index int, count float64) (stop bool) { + s.AddWithCount(index, count) + return false + }) + return + } + if o.minIndex < s.minIndex || o.maxIndex > s.maxIndex { + s.extendRange(o.minIndex, o.maxIndex) + } + idx := o.maxIndex + for ; idx > s.maxIndex && idx >= o.minIndex; idx-- { + s.bins[len(s.bins)-1] += o.bins[idx-o.offset] + } + for ; idx > o.minIndex; idx-- { + s.bins[idx-s.offset] += o.bins[idx-o.offset] + } + // This is a separate test so that the comparison in the previous loop is strict (>) and handles + // o.minIndex = Integer.MIN_VALUE. + if idx == o.minIndex { + s.bins[idx-s.offset] += o.bins[idx-o.offset] + } + s.count += o.count +} + +func (s *CollapsingHighestDenseStore) Copy() Store { + bins := make([]float64, len(s.bins)) + copy(bins, s.bins) + return &CollapsingHighestDenseStore{ + DenseStore: DenseStore{ + bins: bins, + count: s.count, + offset: s.offset, + minIndex: s.minIndex, + maxIndex: s.maxIndex, + }, + maxNumBins: s.maxNumBins, + isCollapsed: s.isCollapsed, + } +} + +func (s *CollapsingHighestDenseStore) Clear() { + s.DenseStore.Clear() + s.isCollapsed = false +} + +func (s *CollapsingHighestDenseStore) DecodeAndMergeWith(r *[]byte, encodingMode enc.SubFlag) error { + return DecodeAndMergeWith(s, r, encodingMode) +} + +var _ Store = (*CollapsingHighestDenseStore)(nil) diff --git a/vendor/github.com/DataDog/sketches-go/ddsketch/store/collapsing_lowest_dense_store.go b/vendor/github.com/DataDog/sketches-go/ddsketch/store/collapsing_lowest_dense_store.go new file mode 100644 index 000000000..80ae2a507 --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/ddsketch/store/collapsing_lowest_dense_store.go @@ -0,0 +1,207 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +package store + +import ( + "math" + + enc "github.com/DataDog/sketches-go/ddsketch/encoding" +) + +// CollapsingLowestDenseStore is a dynamically growing contiguous (non-sparse) store. +// The lower bins get combined so that the total number of bins do not exceed maxNumBins. +type CollapsingLowestDenseStore struct { + DenseStore + maxNumBins int + isCollapsed bool +} + +func NewCollapsingLowestDenseStore(maxNumBins int) *CollapsingLowestDenseStore { + // Bins are not allocated until values are added. + // When the first value is added, a small number of bins are allocated. The number of bins will + // grow as needed up to maxNumBins. + return &CollapsingLowestDenseStore{ + DenseStore: DenseStore{minIndex: math.MaxInt32, maxIndex: math.MinInt32}, + maxNumBins: maxNumBins, + isCollapsed: false, + } +} + +func (s *CollapsingLowestDenseStore) Add(index int) { + s.AddWithCount(index, float64(1)) +} + +func (s *CollapsingLowestDenseStore) AddBin(bin Bin) { + index := bin.Index() + count := bin.Count() + if count == 0 { + return + } + s.AddWithCount(index, count) +} + +func (s *CollapsingLowestDenseStore) AddWithCount(index int, count float64) { + if count == 0 { + return + } + arrayIndex := s.normalize(index) + s.bins[arrayIndex] += count + s.count += count +} + +// Normalize the store, if necessary, so that the counter of the specified index can be updated. +func (s *CollapsingLowestDenseStore) normalize(index int) int { + if index < s.minIndex { + if s.isCollapsed { + return 0 + } else { + s.extendRange(index, index) + if s.isCollapsed { + return 0 + } + } + } else if index > s.maxIndex { + s.extendRange(index, index) + } + return index - s.offset +} + +func (s *CollapsingLowestDenseStore) getNewLength(newMinIndex, newMaxIndex int) int { + return min(s.DenseStore.getNewLength(newMinIndex, newMaxIndex), s.maxNumBins) +} + +func (s *CollapsingLowestDenseStore) extendRange(newMinIndex, newMaxIndex int) { + newMinIndex = min(newMinIndex, s.minIndex) + newMaxIndex = max(newMaxIndex, s.maxIndex) + if s.IsEmpty() { + initialLength := s.getNewLength(newMinIndex, newMaxIndex) + s.bins = append(s.bins, make([]float64, initialLength)...) + s.offset = newMinIndex + s.minIndex = newMinIndex + s.maxIndex = newMaxIndex + s.adjust(newMinIndex, newMaxIndex) + } else if newMinIndex >= s.offset && newMaxIndex < s.offset+len(s.bins) { + s.minIndex = newMinIndex + s.maxIndex = newMaxIndex + } else { + // To avoid shifting too often when nearing the capacity of the array, + // we may grow it before we actually reach the capacity. + newLength := s.getNewLength(newMinIndex, newMaxIndex) + if newLength > len(s.bins) { + s.bins = append(s.bins, make([]float64, newLength-len(s.bins))...) + } + s.adjust(newMinIndex, newMaxIndex) + } +} + +// Adjust bins, offset, minIndex and maxIndex, without resizing the bins slice in order to make it fit the +// specified range. +func (s *CollapsingLowestDenseStore) adjust(newMinIndex, newMaxIndex int) { + if newMaxIndex-newMinIndex+1 > len(s.bins) { + // The range of indices is too wide, buckets of lowest indices need to be collapsed. + newMinIndex = newMaxIndex - len(s.bins) + 1 + if newMinIndex >= s.maxIndex { + // There will be only one non-empty bucket. + s.bins = make([]float64, len(s.bins)) + s.offset = newMinIndex + s.minIndex = newMinIndex + s.bins[0] = s.count + } else { + shift := s.offset - newMinIndex + if shift < 0 { + // Collapse the buckets. + n := float64(0) + for i := s.minIndex; i < newMinIndex; i++ { + n += s.bins[i-s.offset] + } + s.resetBins(s.minIndex, newMinIndex-1) + s.bins[newMinIndex-s.offset] += n + s.minIndex = newMinIndex + // Shift the buckets to make room for newMaxIndex. + s.shiftCounts(shift) + } else { + // Shift the buckets to make room for newMinIndex. + s.shiftCounts(shift) + s.minIndex = newMinIndex + } + } + s.maxIndex = newMaxIndex + s.isCollapsed = true + } else { + s.centerCounts(newMinIndex, newMaxIndex) + } +} + +func (s *CollapsingLowestDenseStore) MergeWith(other Store) { + if other.IsEmpty() { + return + } + o, ok := other.(*CollapsingLowestDenseStore) + if !ok { + other.ForEach(func(index int, count float64) (stop bool) { + s.AddWithCount(index, count) + return false + }) + return + } + if o.minIndex < s.minIndex || o.maxIndex > s.maxIndex { + s.extendRange(o.minIndex, o.maxIndex) + } + idx := o.minIndex + for ; idx < s.minIndex && idx <= o.maxIndex; idx++ { + s.bins[0] += o.bins[idx-o.offset] + } + for ; idx < o.maxIndex; idx++ { + s.bins[idx-s.offset] += o.bins[idx-o.offset] + } + // This is a separate test so that the comparison in the previous loop is strict (<) and handles + // store.maxIndex = Integer.MAX_VALUE. + if idx == o.maxIndex { + s.bins[idx-s.offset] += o.bins[idx-o.offset] + } + s.count += o.count +} + +func (s *CollapsingLowestDenseStore) Copy() Store { + bins := make([]float64, len(s.bins)) + copy(bins, s.bins) + return &CollapsingLowestDenseStore{ + DenseStore: DenseStore{ + bins: bins, + count: s.count, + offset: s.offset, + minIndex: s.minIndex, + maxIndex: s.maxIndex, + }, + maxNumBins: s.maxNumBins, + isCollapsed: s.isCollapsed, + } +} + +func (s *CollapsingLowestDenseStore) Clear() { + s.DenseStore.Clear() + s.isCollapsed = false +} + +func (s *CollapsingLowestDenseStore) DecodeAndMergeWith(r *[]byte, encodingMode enc.SubFlag) error { + return DecodeAndMergeWith(s, r, encodingMode) +} + +var _ Store = (*CollapsingLowestDenseStore)(nil) + +func max(x, y int) int { + if x > y { + return x + } + return y +} + +func min(x, y int) int { + if x < y { + return x + } + return y +} diff --git a/vendor/github.com/DataDog/sketches-go/ddsketch/store/dense_store.go b/vendor/github.com/DataDog/sketches-go/ddsketch/store/dense_store.go new file mode 100644 index 000000000..2c4a3d4a0 --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/ddsketch/store/dense_store.go @@ -0,0 +1,330 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +package store + +import ( + "bytes" + "errors" + "fmt" + "math" + + enc "github.com/DataDog/sketches-go/ddsketch/encoding" + "github.com/DataDog/sketches-go/ddsketch/pb/sketchpb" +) + +const ( + arrayLengthOverhead = 64 + arrayLengthGrowthIncrement = 0.1 + + // Grow the bins with an extra growthBuffer bins to prevent growing too often + growthBuffer = 128 +) + +// DenseStore is a dynamically growing contiguous (non-sparse) store. The number of bins are +// bound only by the size of the slice that can be allocated. +type DenseStore struct { + bins []float64 + count float64 + offset int + minIndex int + maxIndex int +} + +func NewDenseStore() *DenseStore { + return &DenseStore{minIndex: math.MaxInt32, maxIndex: math.MinInt32} +} + +func (s *DenseStore) Add(index int) { + s.AddWithCount(index, float64(1)) +} + +func (s *DenseStore) AddBin(bin Bin) { + if bin.count == 0 { + return + } + s.AddWithCount(bin.index, bin.count) +} + +func (s *DenseStore) AddWithCount(index int, count float64) { + if count == 0 { + return + } + arrayIndex := s.normalize(index) + s.bins[arrayIndex] += count + s.count += count +} + +// Normalize the store, if necessary, so that the counter of the specified index can be updated. +func (s *DenseStore) normalize(index int) int { + if index < s.minIndex || index > s.maxIndex { + s.extendRange(index, index) + } + return index - s.offset +} + +func (s *DenseStore) getNewLength(newMinIndex, newMaxIndex int) int { + desiredLength := newMaxIndex - newMinIndex + 1 + return int((float64(desiredLength+arrayLengthOverhead-1)/arrayLengthGrowthIncrement + 1) * arrayLengthGrowthIncrement) +} + +func (s *DenseStore) extendRange(newMinIndex, newMaxIndex int) { + + newMinIndex = min(newMinIndex, s.minIndex) + newMaxIndex = max(newMaxIndex, s.maxIndex) + + if s.IsEmpty() { + initialLength := s.getNewLength(newMinIndex, newMaxIndex) + s.bins = append(s.bins, make([]float64, initialLength)...) + s.offset = newMinIndex + s.minIndex = newMinIndex + s.maxIndex = newMaxIndex + s.adjust(newMinIndex, newMaxIndex) + } else if newMinIndex >= s.offset && newMaxIndex < s.offset+len(s.bins) { + s.minIndex = newMinIndex + s.maxIndex = newMaxIndex + } else { + // To avoid shifting too often when nearing the capacity of the array, + // we may grow it before we actually reach the capacity. + newLength := s.getNewLength(newMinIndex, newMaxIndex) + if newLength > len(s.bins) { + s.bins = append(s.bins, make([]float64, newLength-len(s.bins))...) + } + s.adjust(newMinIndex, newMaxIndex) + } +} + +// Adjust bins, offset, minIndex and maxIndex, without resizing the bins slice in order to make it fit the +// specified range. +func (s *DenseStore) adjust(newMinIndex, newMaxIndex int) { + s.centerCounts(newMinIndex, newMaxIndex) +} + +func (s *DenseStore) centerCounts(newMinIndex, newMaxIndex int) { + midIndex := newMinIndex + (newMaxIndex-newMinIndex+1)/2 + s.shiftCounts(s.offset + len(s.bins)/2 - midIndex) + s.minIndex = newMinIndex + s.maxIndex = newMaxIndex +} + +func (s *DenseStore) shiftCounts(shift int) { + minArrIndex := s.minIndex - s.offset + maxArrIndex := s.maxIndex - s.offset + copy(s.bins[minArrIndex+shift:], s.bins[minArrIndex:maxArrIndex+1]) + if shift > 0 { + s.resetBins(s.minIndex, s.minIndex+shift-1) + } else { + s.resetBins(s.maxIndex+shift+1, s.maxIndex) + } + s.offset -= shift +} + +func (s *DenseStore) resetBins(fromIndex, toIndex int) { + for i := fromIndex - s.offset; i <= toIndex-s.offset; i++ { + s.bins[i] = 0 + } +} + +func (s *DenseStore) IsEmpty() bool { + return s.count == 0 +} + +func (s *DenseStore) TotalCount() float64 { + return s.count +} + +func (s *DenseStore) MinIndex() (int, error) { + if s.IsEmpty() { + return 0, errUndefinedMinIndex + } + return s.minIndex, nil +} + +func (s *DenseStore) MaxIndex() (int, error) { + if s.IsEmpty() { + return 0, errUndefinedMaxIndex + } + return s.maxIndex, nil +} + +// Return the key for the value at rank +func (s *DenseStore) KeyAtRank(rank float64) int { + if rank < 0 { + rank = 0 + } + var n float64 + for i, b := range s.bins { + n += b + if n > rank { + return i + s.offset + } + } + return s.maxIndex +} + +func (s *DenseStore) MergeWith(other Store) { + if other.IsEmpty() { + return + } + o, ok := other.(*DenseStore) + if !ok { + other.ForEach(func(index int, count float64) (stop bool) { + s.AddWithCount(index, count) + return false + }) + return + } + if o.minIndex < s.minIndex || o.maxIndex > s.maxIndex { + s.extendRange(o.minIndex, o.maxIndex) + } + for idx := o.minIndex; idx <= o.maxIndex; idx++ { + s.bins[idx-s.offset] += o.bins[idx-o.offset] + } + s.count += o.count +} + +func (s *DenseStore) Bins() <-chan Bin { + ch := make(chan Bin) + go func() { + defer close(ch) + for idx := s.minIndex; idx <= s.maxIndex; idx++ { + if s.bins[idx-s.offset] > 0 { + ch <- Bin{index: idx, count: s.bins[idx-s.offset]} + } + } + }() + return ch +} + +func (s *DenseStore) ForEach(f func(index int, count float64) (stop bool)) { + for idx := s.minIndex; idx <= s.maxIndex; idx++ { + if s.bins[idx-s.offset] > 0 { + if f(idx, s.bins[idx-s.offset]) { + return + } + } + } +} + +func (s *DenseStore) Copy() Store { + bins := make([]float64, len(s.bins)) + copy(bins, s.bins) + return &DenseStore{ + bins: bins, + count: s.count, + offset: s.offset, + minIndex: s.minIndex, + maxIndex: s.maxIndex, + } +} + +func (s *DenseStore) Clear() { + s.bins = s.bins[:0] + s.count = 0 + s.minIndex = math.MaxInt32 + s.maxIndex = math.MinInt32 +} + +func (s *DenseStore) string() string { + var buffer bytes.Buffer + buffer.WriteString("{") + for i := 0; i < len(s.bins); i++ { + index := i + s.offset + buffer.WriteString(fmt.Sprintf("%d: %f, ", index, s.bins[i])) + } + buffer.WriteString(fmt.Sprintf("count: %v, offset: %d, minIndex: %d, maxIndex: %d}", s.count, s.offset, s.minIndex, s.maxIndex)) + return buffer.String() +} + +func (s *DenseStore) ToProto() *sketchpb.Store { + if s.IsEmpty() { + return &sketchpb.Store{ContiguousBinCounts: nil} + } + bins := make([]float64, s.maxIndex-s.minIndex+1) + copy(bins, s.bins[s.minIndex-s.offset:s.maxIndex-s.offset+1]) + return &sketchpb.Store{ + ContiguousBinCounts: bins, + ContiguousBinIndexOffset: int32(s.minIndex), + } +} + +func (s *DenseStore) Reweight(w float64) error { + if w <= 0 { + return errors.New("can't reweight by a negative factor") + } + if w == 1 { + return nil + } + s.count *= w + for idx := s.minIndex; idx <= s.maxIndex; idx++ { + s.bins[idx-s.offset] *= w + } + return nil +} + +func (s *DenseStore) Encode(b *[]byte, t enc.FlagType) { + if s.IsEmpty() { + return + } + + denseEncodingSize := 0 + numBins := uint64(s.maxIndex-s.minIndex) + 1 + denseEncodingSize += enc.Uvarint64Size(numBins) + denseEncodingSize += enc.Varint64Size(int64(s.minIndex)) + denseEncodingSize += enc.Varint64Size(1) + + sparseEncodingSize := 0 + numNonEmptyBins := uint64(0) + + previousIndex := s.minIndex + for index := s.minIndex; index <= s.maxIndex; index++ { + count := s.bins[index-s.offset] + countVarFloat64Size := enc.Varfloat64Size(count) + denseEncodingSize += countVarFloat64Size + if count != 0 { + numNonEmptyBins++ + sparseEncodingSize += enc.Varint64Size(int64(index - previousIndex)) + sparseEncodingSize += countVarFloat64Size + previousIndex = index + } + } + sparseEncodingSize += enc.Uvarint64Size(numNonEmptyBins) + + if denseEncodingSize <= sparseEncodingSize { + s.encodeDensely(b, t, numBins) + } else { + s.encodeSparsely(b, t, numNonEmptyBins) + } +} + +func (s *DenseStore) encodeDensely(b *[]byte, t enc.FlagType, numBins uint64) { + enc.EncodeFlag(b, enc.NewFlag(t, enc.BinEncodingContiguousCounts)) + enc.EncodeUvarint64(b, numBins) + enc.EncodeVarint64(b, int64(s.minIndex)) + enc.EncodeVarint64(b, 1) + for index := s.minIndex; index <= s.maxIndex; index++ { + enc.EncodeVarfloat64(b, s.bins[index-s.offset]) + } +} + +func (s *DenseStore) encodeSparsely(b *[]byte, t enc.FlagType, numNonEmptyBins uint64) { + enc.EncodeFlag(b, enc.NewFlag(t, enc.BinEncodingIndexDeltasAndCounts)) + enc.EncodeUvarint64(b, numNonEmptyBins) + previousIndex := 0 + for index := s.minIndex; index <= s.maxIndex; index++ { + count := s.bins[index-s.offset] + if count != 0 { + enc.EncodeVarint64(b, int64(index-previousIndex)) + enc.EncodeVarfloat64(b, count) + previousIndex = index + } + } +} + +func (s *DenseStore) DecodeAndMergeWith(b *[]byte, encodingMode enc.SubFlag) error { + return DecodeAndMergeWith(s, b, encodingMode) +} + +var _ Store = (*DenseStore)(nil) diff --git a/vendor/github.com/DataDog/sketches-go/ddsketch/store/sparse.go b/vendor/github.com/DataDog/sketches-go/ddsketch/store/sparse.go new file mode 100644 index 000000000..9a07836e9 --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/ddsketch/store/sparse.go @@ -0,0 +1,184 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +package store + +import ( + "errors" + "sort" + + enc "github.com/DataDog/sketches-go/ddsketch/encoding" + "github.com/DataDog/sketches-go/ddsketch/pb/sketchpb" +) + +type SparseStore struct { + counts map[int]float64 +} + +func NewSparseStore() *SparseStore { + return &SparseStore{counts: make(map[int]float64)} +} + +func (s *SparseStore) Add(index int) { + s.counts[index]++ +} + +func (s *SparseStore) AddBin(bin Bin) { + s.AddWithCount(bin.index, bin.count) +} + +func (s *SparseStore) AddWithCount(index int, count float64) { + if count == 0 { + return + } + s.counts[index] += count +} + +func (s *SparseStore) Bins() <-chan Bin { + orderedBins := s.orderedBins() + ch := make(chan Bin) + go func() { + defer close(ch) + for _, bin := range orderedBins { + ch <- bin + } + }() + return ch +} + +func (s *SparseStore) orderedBins() []Bin { + bins := make([]Bin, 0, len(s.counts)) + for index, count := range s.counts { + bins = append(bins, Bin{index: index, count: count}) + } + sort.Slice(bins, func(i, j int) bool { return bins[i].index < bins[j].index }) + return bins +} + +func (s *SparseStore) ForEach(f func(index int, count float64) (stop bool)) { + for index, count := range s.counts { + if f(index, count) { + return + } + } +} + +func (s *SparseStore) Copy() Store { + countsCopy := make(map[int]float64) + for index, count := range s.counts { + countsCopy[index] = count + } + return &SparseStore{counts: countsCopy} +} + +func (s *SparseStore) Clear() { + for index := range s.counts { + delete(s.counts, index) + } +} + +func (s *SparseStore) IsEmpty() bool { + return len(s.counts) == 0 +} + +func (s *SparseStore) MaxIndex() (int, error) { + if s.IsEmpty() { + return 0, errUndefinedMaxIndex + } + maxIndex := minInt + for index := range s.counts { + if index > maxIndex { + maxIndex = index + } + } + return maxIndex, nil +} + +func (s *SparseStore) MinIndex() (int, error) { + if s.IsEmpty() { + return 0, errUndefinedMinIndex + } + minIndex := maxInt + for index := range s.counts { + if index < minIndex { + minIndex = index + } + } + return minIndex, nil +} + +func (s *SparseStore) TotalCount() float64 { + totalCount := float64(0) + for _, count := range s.counts { + totalCount += count + } + return totalCount +} + +func (s *SparseStore) KeyAtRank(rank float64) int { + orderedBins := s.orderedBins() + cumulCount := float64(0) + for _, bin := range orderedBins { + cumulCount += bin.count + if cumulCount > rank { + return bin.index + } + } + maxIndex, err := s.MaxIndex() + if err == nil { + return maxIndex + } else { + // FIXME: make Store's KeyAtRank consistent with MinIndex and MaxIndex + return 0 + } +} + +func (s *SparseStore) MergeWith(store Store) { + store.ForEach(func(index int, count float64) (stop bool) { + s.AddWithCount(index, count) + return false + }) +} + +func (s *SparseStore) ToProto() *sketchpb.Store { + binCounts := make(map[int32]float64) + for index, count := range s.counts { + binCounts[int32(index)] = count + } + return &sketchpb.Store{BinCounts: binCounts} +} + +func (s *SparseStore) Reweight(w float64) error { + if w <= 0 { + return errors.New("can't reweight by a negative factor") + } + if w == 1 { + return nil + } + for index := range s.counts { + s.counts[index] *= w + } + return nil +} + +func (s *SparseStore) Encode(b *[]byte, t enc.FlagType) { + if s.IsEmpty() { + return + } + enc.EncodeFlag(b, enc.NewFlag(t, enc.BinEncodingIndexDeltasAndCounts)) + enc.EncodeUvarint64(b, uint64(len(s.counts))) + previousIndex := 0 + for index, count := range s.counts { + enc.EncodeVarint64(b, int64(index-previousIndex)) + enc.EncodeVarfloat64(b, count) + previousIndex = index + } +} + +func (s *SparseStore) DecodeAndMergeWith(b *[]byte, encodingMode enc.SubFlag) error { + return DecodeAndMergeWith(s, b, encodingMode) +} + +var _ Store = (*SparseStore)(nil) diff --git a/vendor/github.com/DataDog/sketches-go/ddsketch/store/store.go b/vendor/github.com/DataDog/sketches-go/ddsketch/store/store.go new file mode 100644 index 000000000..64a5e3d50 --- /dev/null +++ b/vendor/github.com/DataDog/sketches-go/ddsketch/store/store.go @@ -0,0 +1,153 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +package store + +import ( + "errors" + + enc "github.com/DataDog/sketches-go/ddsketch/encoding" + "github.com/DataDog/sketches-go/ddsketch/pb/sketchpb" +) + +type Provider func() Store + +var ( + DefaultProvider = Provider(BufferedPaginatedStoreConstructor) + DenseStoreConstructor = Provider(func() Store { return NewDenseStore() }) + BufferedPaginatedStoreConstructor = Provider(func() Store { return NewBufferedPaginatedStore() }) + SparseStoreConstructor = Provider(func() Store { return NewSparseStore() }) +) + +const ( + maxInt = int(^uint(0) >> 1) + minInt = ^maxInt +) + +var ( + errUndefinedMinIndex = errors.New("MinIndex of empty store is undefined") + errUndefinedMaxIndex = errors.New("MaxIndex of empty store is undefined") +) + +type Store interface { + Add(index int) + AddBin(bin Bin) + AddWithCount(index int, count float64) + // Bins returns a channel that emits the bins that are encoded in the store. + // Note that this leaks a channel and a goroutine if it is not iterated to completion. + Bins() <-chan Bin + // ForEach applies f to all elements of the store or until f returns true. + ForEach(f func(index int, count float64) (stop bool)) + Copy() Store + // Clear empties the store while allowing reusing already allocated memory. + // In some situations, it may be advantageous to clear and reuse a store + // rather than instantiating a new one. Keeping reusing the same store again + // and again on varying input data distributions may however ultimately make + // the store overly large and may waste memory space. + Clear() + IsEmpty() bool + MaxIndex() (int, error) + MinIndex() (int, error) + TotalCount() float64 + KeyAtRank(rank float64) int + MergeWith(store Store) + ToProto() *sketchpb.Store + // Reweight multiplies all values from the store by w, but keeps the same global distribution. + Reweight(w float64) error + // Encode encodes the bins of the store and appends its content to the + // provided []byte. + // The provided FlagType indicates whether the store encodes positive or + // negative values. + Encode(b *[]byte, t enc.FlagType) + // DecodeAndMergeWith decodes bins that have been encoded in the format of + // the provided binEncodingMode and merges them within the receiver store. + // It updates the provided []byte so that it starts immediately after the + // encoded bins. + DecodeAndMergeWith(b *[]byte, binEncodingMode enc.SubFlag) error +} + +// FromProto returns an instance of DenseStore that contains the data in the provided protobuf representation. +func FromProto(pb *sketchpb.Store) *DenseStore { + store := NewDenseStore() + MergeWithProto(store, pb) + return store +} + +// MergeWithProto merges the distribution in a protobuf Store to an existing store. +// - if called with an empty store, this simply populates the store with the distribution in the protobuf Store. +// - if called with a non-empty store, this has the same outcome as deserializing the protobuf Store, then merging. +func MergeWithProto(store Store, pb *sketchpb.Store) { + for idx, count := range pb.BinCounts { + store.AddWithCount(int(idx), count) + } + for idx, count := range pb.ContiguousBinCounts { + store.AddWithCount(idx+int(pb.ContiguousBinIndexOffset), count) + } +} + +func DecodeAndMergeWith(s Store, b *[]byte, binEncodingMode enc.SubFlag) error { + switch binEncodingMode { + + case enc.BinEncodingIndexDeltasAndCounts: + numBins, err := enc.DecodeUvarint64(b) + if err != nil { + return err + } + index := int64(0) + for i := uint64(0); i < numBins; i++ { + indexDelta, err := enc.DecodeVarint64(b) + if err != nil { + return err + } + count, err := enc.DecodeVarfloat64(b) + if err != nil { + return err + } + index += indexDelta + s.AddWithCount(int(index), count) + } + + case enc.BinEncodingIndexDeltas: + numBins, err := enc.DecodeUvarint64(b) + if err != nil { + return err + } + index := int64(0) + for i := uint64(0); i < numBins; i++ { + indexDelta, err := enc.DecodeVarint64(b) + if err != nil { + return err + } + index += indexDelta + s.Add(int(index)) + } + + case enc.BinEncodingContiguousCounts: + numBins, err := enc.DecodeUvarint64(b) + if err != nil { + return err + } + index, err := enc.DecodeVarint64(b) + if err != nil { + return err + } + indexDelta, err := enc.DecodeVarint64(b) + if err != nil { + return err + } + for i := uint64(0); i < numBins; i++ { + count, err := enc.DecodeVarfloat64(b) + if err != nil { + return err + } + s.AddWithCount(int(index), count) + index += indexDelta + } + + default: + return errors.New("unknown bin encoding") + } + return nil +} diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/armor.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/armor.go index 0d6c5f3f9..d7af9141e 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/armor.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/armor/armor.go @@ -10,8 +10,9 @@ import ( "bufio" "bytes" "encoding/base64" - "github.com/ProtonMail/go-crypto/openpgp/errors" "io" + + "github.com/ProtonMail/go-crypto/openpgp/errors" ) // A Block represents an OpenPGP armored structure. @@ -208,12 +209,16 @@ TryNextBlock: break } - i := bytes.Index(line, []byte(": ")) + i := bytes.Index(line, []byte(":")) if i == -1 { goto TryNextBlock } lastKey = string(line[:i]) - p.Header[lastKey] = string(line[i+2:]) + var value string + if len(line) > i+2 { + value = string(line[i+2:]) + } + p.Header[lastKey] = value } p.lReader.in = r diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go index ffdd51513..df04262e9 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/internal/ecc/x448.go @@ -73,7 +73,9 @@ func (c *x448) GenerateECDH(rand io.Reader) (point []byte, secret []byte, err er func (c *x448) Encaps(rand io.Reader, point []byte) (ephemeral, sharedSecret []byte, err error) { var pk, ss x448lib.Key seed, e, err := c.generateKeyPairBytes(rand) - + if err != nil { + return nil, nil, err + } copy(pk[:], point) x448lib.Shared(&ss, &seed, &pk) diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go index 7283ca91c..2d7b0cf37 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/keys.go @@ -504,7 +504,7 @@ EachPacket: // Else, ignoring the signature as it does not follow anything // we would know to attach it to. case *packet.PrivateKey: - if pkt.IsSubkey == false { + if !pkt.IsSubkey { packets.Unread(p) break EachPacket } @@ -513,7 +513,7 @@ EachPacket: return nil, err } case *packet.PublicKey: - if pkt.IsSubkey == false { + if !pkt.IsSubkey { packets.Unread(p) break EachPacket } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go index ec903ee95..3402b8c14 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go @@ -415,6 +415,10 @@ func (pk *PublicKey) parseEdDSA(r io.Reader) (err error) { return } + if len(pk.p.Bytes()) == 0 { + return errors.StructuralError("empty EdDSA public key") + } + pub := eddsa.NewPublicKey(c) switch flag := pk.p.Bytes()[0]; flag { diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go index 6c58c86fa..80d0bb98e 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go @@ -904,7 +904,7 @@ func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubp if sig.IssuerKeyId != nil && sig.Version == 4 { keyId := make([]byte, 8) binary.BigEndian.PutUint64(keyId, *sig.IssuerKeyId) - subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, true, keyId}) + subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, false, keyId}) } if sig.IssuerFingerprint != nil { contents := append([]uint8{uint8(issuer.Version)}, sig.IssuerFingerprint...) diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetric_key_encrypted.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetric_key_encrypted.go index a8abf2ff7..bac2b132e 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetric_key_encrypted.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetric_key_encrypted.go @@ -7,13 +7,11 @@ package packet import ( "bytes" "crypto/cipher" - "crypto/sha256" "io" "strconv" "github.com/ProtonMail/go-crypto/openpgp/errors" "github.com/ProtonMail/go-crypto/openpgp/s2k" - "golang.org/x/crypto/hkdf" ) // This is the largest session key that we'll support. Since at most 256-bit cipher @@ -45,13 +43,6 @@ func (ske *SymmetricKeyEncrypted) parse(r io.Reader) error { return errors.UnsupportedError("unknown SymmetricKeyEncrypted version") } - if ske.Version == 5 { - // Scalar octet count - if _, err := readFull(r, buf[:]); err != nil { - return err - } - } - // Cipher function if _, err := readFull(r, buf[:]); err != nil { return err @@ -67,11 +58,6 @@ func (ske *SymmetricKeyEncrypted) parse(r io.Reader) error { return errors.StructuralError("cannot read AEAD octet from packet") } ske.Mode = AEADMode(buf[0]) - - // Scalar octet count - if _, err := readFull(r, buf[:]); err != nil { - return err - } } var err error @@ -220,7 +206,7 @@ func SerializeSymmetricKeyEncryptedReuseKey(w io.Writer, sessionKey []byte, pass case 5: ivLen := config.AEAD().Mode().IvLength() tagLen := config.AEAD().Mode().TagLength() - packetLength = 5 + len(s2kBytes) + ivLen + keySize + tagLen + packetLength = 3 + len(s2kBytes) + ivLen + keySize + tagLen } err = serializeHeader(w, packetTypeSymmetricKeyEncrypted, packetLength) if err != nil { @@ -230,20 +216,12 @@ func SerializeSymmetricKeyEncryptedReuseKey(w io.Writer, sessionKey []byte, pass // Symmetric Key Encrypted Version buf := []byte{byte(version)} - if version == 5 { - // Scalar octet count - buf = append(buf, byte(3+len(s2kBytes)+config.AEAD().Mode().IvLength())) - } - // Cipher function buf = append(buf, byte(cipherFunc)) if version == 5 { // AEAD mode buf = append(buf, byte(config.AEAD().Mode())) - - // Scalar octet count - buf = append(buf, byte(len(s2kBytes))) } _, err = w.Write(buf) if err != nil { @@ -293,11 +271,6 @@ func SerializeSymmetricKeyEncryptedReuseKey(w io.Writer, sessionKey []byte, pass } func getEncryptedKeyAeadInstance(c CipherFunction, mode AEADMode, inputKey, associatedData []byte) (aead cipher.AEAD) { - hkdfReader := hkdf.New(sha256.New, inputKey, []byte{}, associatedData) - - encryptionKey := make([]byte, c.KeySize()) - _, _ = readFull(hkdfReader, encryptionKey) - - blockCipher := c.new(encryptionKey) + blockCipher := c.new(inputKey) return mode.new(blockCipher) } diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go index 609e9fc1f..e9bbf0327 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted.go @@ -24,10 +24,10 @@ type SymmetricallyEncrypted struct { prefix []byte // Specific to version 2 - cipher CipherFunction - mode AEADMode - chunkSizeByte byte - salt [aeadSaltSize]byte + Cipher CipherFunction + Mode AEADMode + ChunkSizeByte byte + Salt [aeadSaltSize]byte } const ( diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go index 969c42236..e96252c19 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/symmetrically_encrypted_aead.go @@ -7,9 +7,10 @@ package packet import ( "crypto/cipher" "crypto/sha256" + "io" + "github.com/ProtonMail/go-crypto/openpgp/errors" "golang.org/x/crypto/hkdf" - "io" ) // parseAead parses a V2 SEIPD packet (AEAD) as specified in @@ -21,26 +22,26 @@ func (se *SymmetricallyEncrypted) parseAead(r io.Reader) error { } // Cipher - se.cipher = CipherFunction(headerData[0]) + se.Cipher = CipherFunction(headerData[0]) // cipherFunc must have block size 16 to use AEAD - if se.cipher.blockSize() != 16 { - return errors.UnsupportedError("invalid aead cipher: " + string(se.cipher)) + if se.Cipher.blockSize() != 16 { + return errors.UnsupportedError("invalid aead cipher: " + string(se.Cipher)) } // Mode - se.mode = AEADMode(headerData[1]) - if se.mode.TagLength() == 0 { - return errors.UnsupportedError("unknown aead mode: " + string(se.mode)) + se.Mode = AEADMode(headerData[1]) + if se.Mode.TagLength() == 0 { + return errors.UnsupportedError("unknown aead mode: " + string(se.Mode)) } // Chunk size - se.chunkSizeByte = headerData[2] - if se.chunkSizeByte > 16 { - return errors.UnsupportedError("invalid aead chunk size byte: " + string(se.chunkSizeByte)) + se.ChunkSizeByte = headerData[2] + if se.ChunkSizeByte > 16 { + return errors.UnsupportedError("invalid aead chunk size byte: " + string(se.ChunkSizeByte)) } // Salt - if n, err := io.ReadFull(r, se.salt[:]); n < aeadSaltSize { + if n, err := io.ReadFull(r, se.Salt[:]); n < aeadSaltSize { return errors.StructuralError("could not read aead salt: " + err.Error()) } @@ -52,19 +53,19 @@ func (se *SymmetricallyEncrypted) associatedData() []byte { return []byte{ 0xD2, symmetricallyEncryptedVersionAead, - byte(se.cipher), - byte(se.mode), - se.chunkSizeByte, + byte(se.Cipher), + byte(se.Mode), + se.ChunkSizeByte, } } // decryptAead decrypts a V2 SEIPD packet (AEAD) as specified in // https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2 func (se *SymmetricallyEncrypted) decryptAead(inputKey []byte) (io.ReadCloser, error) { - aead, nonce := getSymmetricallyEncryptedAeadInstance(se.cipher, se.mode, inputKey, se.salt[:], se.associatedData()) + aead, nonce := getSymmetricallyEncryptedAeadInstance(se.Cipher, se.Mode, inputKey, se.Salt[:], se.associatedData()) // Carry the first tagLen bytes - tagLen := se.mode.TagLength() + tagLen := se.Mode.TagLength() peekedBytes := make([]byte, tagLen) n, err := io.ReadFull(se.Contents, peekedBytes) if n < tagLen || (err != nil && err != io.EOF) { @@ -74,7 +75,7 @@ func (se *SymmetricallyEncrypted) decryptAead(inputKey []byte) (io.ReadCloser, e return &aeadDecrypter{ aeadCrypter: aeadCrypter{ aead: aead, - chunkSize: decodeAEADChunkSize(se.chunkSizeByte), + chunkSize: decodeAEADChunkSize(se.ChunkSizeByte), initialNonce: nonce, associatedData: se.associatedData(), chunkIndex: make([]byte, 8), diff --git a/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go b/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go index 864d8ca6b..7fdd13a3d 100644 --- a/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go +++ b/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go @@ -381,7 +381,7 @@ func encrypt(keyWriter io.Writer, dataWriter io.Writer, to []*Entity, signed *En } sig := to[i].PrimaryIdentity().SelfSignature - if sig.SEIPDv2 == false { + if !sig.SEIPDv2 { aeadSupported = false } diff --git a/vendor/github.com/alibabacloud-go/darabonba-openapi/client/client.go b/vendor/github.com/alibabacloud-go/darabonba-openapi/client/client.go index 6da3e1fdd..e014c11ff 100644 --- a/vendor/github.com/alibabacloud-go/darabonba-openapi/client/client.go +++ b/vendor/github.com/alibabacloud-go/darabonba-openapi/client/client.go @@ -15,6 +15,29 @@ import ( credential "github.com/aliyun/credentials-go/credentials" ) +type GlobalParameters struct { + Headers map[string]*string `json:"headers,omitempty" xml:"headers,omitempty"` + Queries map[string]*string `json:"queries,omitempty" xml:"queries,omitempty"` +} + +func (s GlobalParameters) String() string { + return tea.Prettify(s) +} + +func (s GlobalParameters) GoString() string { + return s.String() +} + +func (s *GlobalParameters) SetHeaders(v map[string]*string) *GlobalParameters { + s.Headers = v + return s +} + +func (s *GlobalParameters) SetQueries(v map[string]*string) *GlobalParameters { + s.Queries = v + return s +} + /** * Model for initing client */ @@ -68,6 +91,8 @@ type Config struct { SignatureVersion *string `json:"signatureVersion,omitempty" xml:"signatureVersion,omitempty"` // Signature Algorithm SignatureAlgorithm *string `json:"signatureAlgorithm,omitempty" xml:"signatureAlgorithm,omitempty"` + // Global Parameters + GlobalParameters *GlobalParameters `json:"globalParameters,omitempty" xml:"globalParameters,omitempty"` } func (s Config) String() string { @@ -198,6 +223,11 @@ func (s *Config) SetSignatureAlgorithm(v string) *Config { return s } +func (s *Config) SetGlobalParameters(v *GlobalParameters) *Config { + s.GlobalParameters = v + return s +} + type OpenApiRequest struct { Headers map[string]*string `json:"headers,omitempty" xml:"headers,omitempty"` Query map[string]*string `json:"query,omitempty" xml:"query,omitempty"` @@ -336,6 +366,7 @@ type Client struct { SignatureAlgorithm *string Headers map[string]*string Spi spi.ClientInterface + GlobalParameters *GlobalParameters } /** @@ -397,6 +428,7 @@ func (client *Client) Init(config *Config) (_err error) { client.MaxIdleConns = config.MaxIdleConns client.SignatureVersion = config.SignatureVersion client.SignatureAlgorithm = config.SignatureAlgorithm + client.GlobalParameters = config.GlobalParameters return nil } @@ -1085,7 +1117,22 @@ func (client *Client) DoRequest(params *Params, request *OpenApiRequest, runtime request_.Protocol = util.DefaultString(client.Protocol, params.Protocol) request_.Method = params.Method request_.Pathname = params.Pathname - request_.Query = request.Query + globalQueries := make(map[string]*string) + globalHeaders := make(map[string]*string) + if !tea.BoolValue(util.IsUnset(tea.ToMap(client.GlobalParameters))) { + globalParams := client.GlobalParameters + if !tea.BoolValue(util.IsUnset(globalParams.Queries)) { + globalQueries = globalParams.Queries + } + + if !tea.BoolValue(util.IsUnset(globalParams.Headers)) { + globalHeaders = globalParams.Headers + } + + } + + request_.Query = tea.Merge(globalQueries, + request.Query) // endpoint is setted in product client request_.Headers = tea.Merge(map[string]*string{ "host": client.Endpoint, @@ -1095,7 +1142,8 @@ func (client *Client) DoRequest(params *Params, request *OpenApiRequest, runtime "x-acs-date": openapiutil.GetTimestamp(), "x-acs-signature-nonce": util.GetNonce(), "accept": tea.String("application/json"), - }, request.Headers) + }, globalHeaders, + request.Headers) if tea.BoolValue(util.EqualString(params.Style, tea.String("RPC"))) { headers, _err := client.GetRpcHeaders() if _err != nil { @@ -1213,8 +1261,9 @@ func (client *Client) DoRequest(params *Params, request *OpenApiRequest, runtime if tea.BoolValue(util.EqualString(params.BodyType, tea.String("binary"))) { resp := map[string]interface{}{ - "body": response_.Body, - "headers": response_.Headers, + "body": response_.Body, + "headers": response_.Headers, + "statusCode": tea.IntValue(response_.StatusCode), } _result = resp return _result, _err @@ -1226,8 +1275,9 @@ func (client *Client) DoRequest(params *Params, request *OpenApiRequest, runtime _result = make(map[string]interface{}) _err = tea.Convert(map[string]interface{}{ - "body": byt, - "headers": response_.Headers, + "body": byt, + "headers": response_.Headers, + "statusCode": tea.IntValue(response_.StatusCode), }, &_result) return _result, _err } else if tea.BoolValue(util.EqualString(params.BodyType, tea.String("string"))) { @@ -1238,8 +1288,9 @@ func (client *Client) DoRequest(params *Params, request *OpenApiRequest, runtime _result = make(map[string]interface{}) _err = tea.Convert(map[string]interface{}{ - "body": tea.StringValue(str), - "headers": response_.Headers, + "body": tea.StringValue(str), + "headers": response_.Headers, + "statusCode": tea.IntValue(response_.StatusCode), }, &_result) return _result, _err } else if tea.BoolValue(util.EqualString(params.BodyType, tea.String("json"))) { @@ -1251,8 +1302,9 @@ func (client *Client) DoRequest(params *Params, request *OpenApiRequest, runtime res := util.AssertAsMap(obj) _result = make(map[string]interface{}) _err = tea.Convert(map[string]interface{}{ - "body": res, - "headers": response_.Headers, + "body": res, + "headers": response_.Headers, + "statusCode": tea.IntValue(response_.StatusCode), }, &_result) return _result, _err } else if tea.BoolValue(util.EqualString(params.BodyType, tea.String("array"))) { @@ -1263,14 +1315,16 @@ func (client *Client) DoRequest(params *Params, request *OpenApiRequest, runtime _result = make(map[string]interface{}) _err = tea.Convert(map[string]interface{}{ - "body": arr, - "headers": response_.Headers, + "body": arr, + "headers": response_.Headers, + "statusCode": tea.IntValue(response_.StatusCode), }, &_result) return _result, _err } else { _result = make(map[string]interface{}) - _err = tea.Convert(map[string]map[string]*string{ - "headers": response_.Headers, + _err = tea.Convert(map[string]interface{}{ + "headers": response_.Headers, + "statusCode": tea.IntValue(response_.StatusCode), }, &_result) return _result, _err } @@ -1347,10 +1401,26 @@ func (client *Client) Execute(params *Params, request *OpenApiRequest, runtime * return _result, _err } + globalQueries := make(map[string]*string) + globalHeaders := make(map[string]*string) + if !tea.BoolValue(util.IsUnset(tea.ToMap(client.GlobalParameters))) { + globalParams := client.GlobalParameters + if !tea.BoolValue(util.IsUnset(globalParams.Queries)) { + globalQueries = globalParams.Queries + } + + if !tea.BoolValue(util.IsUnset(globalParams.Headers)) { + globalHeaders = globalParams.Headers + } + + } + requestContext := &spi.InterceptorContextRequest{ - Headers: tea.Merge(request.Headers, + Headers: tea.Merge(globalHeaders, + request.Headers, headers), - Query: request.Query, + Query: tea.Merge(globalQueries, + request.Query), Body: request.Body, Stream: request.Stream, HostMap: request.HostMap, @@ -1416,8 +1486,9 @@ func (client *Client) Execute(params *Params, request *OpenApiRequest, runtime * } _result = make(map[string]interface{}) _err = tea.Convert(map[string]interface{}{ - "headers": interceptorContext.Response.Headers, - "body": interceptorContext.Response.DeserializedBody, + "headers": interceptorContext.Response.Headers, + "statusCode": tea.IntValue(interceptorContext.Response.StatusCode), + "body": interceptorContext.Response.DeserializedBody, }, &_result) return _result, _err }() diff --git a/vendor/github.com/alibabacloud-go/tea-utils/service/service.go b/vendor/github.com/alibabacloud-go/tea-utils/service/service.go index 2b6935723..51ce5acc1 100644 --- a/vendor/github.com/alibabacloud-go/tea-utils/service/service.go +++ b/vendor/github.com/alibabacloud-go/tea-utils/service/service.go @@ -34,6 +34,7 @@ type RuntimeOptions struct { MaxIdleConns *int `json:"maxIdleConns" xml:"maxIdleConns"` Socks5Proxy *string `json:"socks5Proxy" xml:"socks5Proxy"` Socks5NetWork *string `json:"socks5NetWork" xml:"socks5NetWork"` + KeepAlive *bool `json:"keepAlive" xml:"keepAlive"` } func (s RuntimeOptions) String() string { @@ -114,6 +115,11 @@ func (s *RuntimeOptions) SetSocks5NetWork(v string) *RuntimeOptions { return s } +func (s *RuntimeOptions) SetKeepAlive(v bool) *RuntimeOptions { + s.KeepAlive = &v + return s +} + func ReadAsString(body io.Reader) (*string, error) { byt, err := ioutil.ReadAll(body) if err != nil { diff --git a/vendor/github.com/alibabacloud-go/tea-xml/LICENSE b/vendor/github.com/alibabacloud-go/tea-xml/LICENSE new file mode 100644 index 000000000..0c44dcefe --- /dev/null +++ b/vendor/github.com/alibabacloud-go/tea-xml/LICENSE @@ -0,0 +1,201 @@ + 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 (c) 2009-present, Alibaba Cloud All rights reserved. + + 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/alibabacloud-go/tea/tea/tea.go b/vendor/github.com/alibabacloud-go/tea/tea/tea.go index 4fbddd3cb..c984caf82 100644 --- a/vendor/github.com/alibabacloud-go/tea/tea/tea.go +++ b/vendor/github.com/alibabacloud-go/tea/tea/tea.go @@ -69,12 +69,14 @@ type Response struct { // SDKError struct is used save error code and message type SDKError struct { - Code *string - StatusCode *int - Message *string - Data *string - Stack *string - errMsg *string + Code *string + StatusCode *int + Message *string + Data *string + Stack *string + errMsg *string + Description *string + AccessDeniedDetail map[string]interface{} } // RuntimeObject is used for converting http configuration @@ -181,6 +183,20 @@ func NewSDKError(obj map[string]interface{}) *SDKError { if obj["message"] != nil { err.Message = String(obj["message"].(string)) } + if obj["description"] != nil { + err.Description = String(obj["description"].(string)) + } + if detail := obj["accessDeniedDetail"]; detail != nil { + r := reflect.ValueOf(detail) + if r.Kind().String() == "map" { + res := make(map[string]interface{}) + tmp := r.MapKeys() + for _, key := range tmp { + res[key.String()] = r.MapIndex(key).Interface() + } + err.AccessDeniedDetail = res + } + } if data := obj["data"]; data != nil { r := reflect.ValueOf(data) if r.Kind().String() == "map" { @@ -197,6 +213,8 @@ func NewSDKError(obj map[string]interface{}) *SDKError { if err_ == nil { err.StatusCode = Int(code) } + } else if code, ok := statusCode.(*int); ok { + err.StatusCode = code } } } @@ -244,7 +262,7 @@ func Convert(in interface{}, out interface{}) error { return err } -// Convert is use convert map[string]interface object to struct +// Recover is used to format error func Recover(in interface{}) error { if in == nil { return nil @@ -304,6 +322,9 @@ func DoRequest(request *Request, requestRuntime map[string]interface{}) (respons requestURL := "" request.Domain = request.Headers["host"] + if request.Port != nil { + request.Domain = String(fmt.Sprintf("%s:%d", StringValue(request.Domain), IntValue(request.Port))) + } requestURL = fmt.Sprintf("%s://%s%s", StringValue(request.Protocol), StringValue(request.Domain), StringValue(request.Pathname)) queryParams := request.Query // sort QueryParams by key @@ -394,28 +415,30 @@ func getHttpTransport(req *Request, runtime *RuntimeObject) (*http.Transport, er if err != nil { return nil, err } - if strings.ToLower(*req.Protocol) == "https" && - runtime.Key != nil && runtime.Cert != nil { - cert, err := tls.X509KeyPair([]byte(StringValue(runtime.Cert)), []byte(StringValue(runtime.Key))) - if err != nil { - return nil, err - } - - trans.TLSClientConfig = &tls.Config{ - Certificates: []tls.Certificate{cert}, - InsecureSkipVerify: BoolValue(runtime.IgnoreSSL), - } - if runtime.CA != nil { - clientCertPool := x509.NewCertPool() - ok := clientCertPool.AppendCertsFromPEM([]byte(StringValue(runtime.CA))) - if !ok { - return nil, errors.New("Failed to parse root certificate") + if strings.ToLower(*req.Protocol) == "https" { + if BoolValue(runtime.IgnoreSSL) != true { + trans.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: false, + } + if runtime.Key != nil && runtime.Cert != nil && StringValue(runtime.Key) != "" && StringValue(runtime.Cert) != "" { + cert, err := tls.X509KeyPair([]byte(StringValue(runtime.Cert)), []byte(StringValue(runtime.Key))) + if err != nil { + return nil, err + } + trans.TLSClientConfig.Certificates = []tls.Certificate{cert} + } + if runtime.CA != nil && StringValue(runtime.CA) != "" { + clientCertPool := x509.NewCertPool() + ok := clientCertPool.AppendCertsFromPEM([]byte(StringValue(runtime.CA))) + if !ok { + return nil, errors.New("Failed to parse root certificate") + } + trans.TLSClientConfig.RootCAs = clientCertPool + } + } else { + trans.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: true, } - trans.TLSClientConfig.RootCAs = clientCertPool - } - } else { - trans.TLSClientConfig = &tls.Config{ - InsecureSkipVerify: BoolValue(runtime.IgnoreSSL), } } if httpProxy != nil { @@ -455,6 +478,10 @@ func getHttpTransport(req *Request, runtime *RuntimeObject) (*http.Transport, er } else { trans.DialContext = setDialContext(runtime) } + if runtime.MaxIdleConns != nil && *runtime.MaxIdleConns > 0 { + trans.MaxIdleConns = IntValue(runtime.MaxIdleConns) + trans.MaxIdleConnsPerHost = IntValue(runtime.MaxIdleConns) + } return trans, nil } diff --git a/vendor/github.com/aliyun/credentials-go/credentials/access_key_credential.go b/vendor/github.com/aliyun/credentials-go/credentials/access_key_credential.go index 7bcaa9740..78530e689 100644 --- a/vendor/github.com/aliyun/credentials-go/credentials/access_key_credential.go +++ b/vendor/github.com/aliyun/credentials-go/credentials/access_key_credential.go @@ -15,6 +15,15 @@ func newAccessKeyCredential(accessKeyId, accessKeySecret string) *AccessKeyCrede } } +func (s *AccessKeyCredential) GetCredential() (*CredentialModel, error) { + credential := &CredentialModel{ + AccessKeyId: tea.String(s.AccessKeyId), + AccessKeySecret: tea.String(s.AccessKeySecret), + Type: tea.String("access_key"), + } + return credential, nil +} + // GetAccessKeyId reutrns AccessKeyCreential's AccessKeyId func (a *AccessKeyCredential) GetAccessKeyId() (*string, error) { return tea.String(a.AccessKeyId), nil diff --git a/vendor/github.com/aliyun/credentials-go/credentials/bearer_token_credential.go b/vendor/github.com/aliyun/credentials-go/credentials/bearer_token_credential.go index cca291621..9df4d3202 100644 --- a/vendor/github.com/aliyun/credentials-go/credentials/bearer_token_credential.go +++ b/vendor/github.com/aliyun/credentials-go/credentials/bearer_token_credential.go @@ -14,6 +14,14 @@ func newBearerTokenCredential(token string) *BearerTokenCredential { } } +func (s *BearerTokenCredential) GetCredential() (*CredentialModel, error) { + credential := &CredentialModel{ + BearerToken: tea.String(s.BearerToken), + Type: tea.String("bearer"), + } + return credential, nil +} + // GetAccessKeyId is useless for BearerTokenCredential func (b *BearerTokenCredential) GetAccessKeyId() (*string, error) { return tea.String(""), nil diff --git a/vendor/github.com/aliyun/credentials-go/credentials/credential.go b/vendor/github.com/aliyun/credentials-go/credentials/credential.go index 62e647541..2603dc0c7 100644 --- a/vendor/github.com/aliyun/credentials-go/credentials/credential.go +++ b/vendor/github.com/aliyun/credentials-go/credentials/credential.go @@ -30,6 +30,7 @@ type Credential interface { GetSecurityToken() (*string, error) GetBearerToken() *string GetType() *string + GetCredential() (*CredentialModel, error) } // Config is important when call NewCredential @@ -55,6 +56,8 @@ type Config struct { Proxy *string `json:"proxy"` InAdvanceScale *float64 `json:"inAdvanceScale"` Url *string `json:"url"` + STSEndpoint *string `json:"sts_endpoint"` + ExternalId *string `json:"external_id"` } func (s Config) String() string { @@ -168,6 +171,11 @@ func (s *Config) SetURLCredential(v string) *Config { return s } +func (s *Config) SetSTSEndpoint(v string) *Config { + s.STSEndpoint = &v + return s +} + // NewCredential return a credential according to the type in config. // if config is nil, the function will use default provider chain to get credential. // please see README.md for detail. @@ -192,6 +200,7 @@ func NewCredential(config *Config) (credential Credential, err error) { Proxy: tea.StringValue(config.Proxy), ReadTimeout: tea.IntValue(config.Timeout), ConnectTimeout: tea.IntValue(config.ConnectTimeout), + STSEndpoint: tea.StringValue(config.STSEndpoint), } credential = newOIDCRoleArnCredential(tea.StringValue(config.AccessKeyId), tea.StringValue(config.AccessKeySecret), tea.StringValue(config.RoleArn), tea.StringValue(config.OIDCProviderArn), tea.StringValue(config.OIDCTokenFilePath), tea.StringValue(config.RoleSessionName), tea.StringValue(config.Policy), tea.IntValue(config.RoleSessionExpiration), runtime) case "access_key": @@ -225,8 +234,17 @@ func NewCredential(config *Config) (credential Credential, err error) { Proxy: tea.StringValue(config.Proxy), ReadTimeout: tea.IntValue(config.Timeout), ConnectTimeout: tea.IntValue(config.ConnectTimeout), + STSEndpoint: tea.StringValue(config.STSEndpoint), } - credential = newRAMRoleArnCredential(tea.StringValue(config.AccessKeyId), tea.StringValue(config.AccessKeySecret), tea.StringValue(config.RoleArn), tea.StringValue(config.RoleSessionName), tea.StringValue(config.Policy), tea.IntValue(config.RoleSessionExpiration), runtime) + credential = newRAMRoleArnWithExternalIdCredential( + tea.StringValue(config.AccessKeyId), + tea.StringValue(config.AccessKeySecret), + tea.StringValue(config.RoleArn), + tea.StringValue(config.RoleSessionName), + tea.StringValue(config.Policy), + tea.IntValue(config.RoleSessionExpiration), + tea.StringValue(config.ExternalId), + runtime) case "rsa_key_pair": err = checkRSAKeyPair(config) if err != nil { @@ -251,6 +269,7 @@ func NewCredential(config *Config) (credential Credential, err error) { Proxy: tea.StringValue(config.Proxy), ReadTimeout: tea.IntValue(config.Timeout), ConnectTimeout: tea.IntValue(config.ConnectTimeout), + STSEndpoint: tea.StringValue(config.STSEndpoint), } credential = newRsaKeyPairCredential(privateKey, tea.StringValue(config.PublicKeyId), tea.IntValue(config.SessionExpiration), runtime) case "bearer": diff --git a/vendor/github.com/aliyun/credentials-go/credentials/credential_model.go b/vendor/github.com/aliyun/credentials-go/credentials/credential_model.go new file mode 100644 index 000000000..7b46c3088 --- /dev/null +++ b/vendor/github.com/aliyun/credentials-go/credentials/credential_model.go @@ -0,0 +1,50 @@ +package credentials + +import "github.com/alibabacloud-go/tea/tea" + +// CredentialModel is a model +type CredentialModel struct { + // accesskey id + AccessKeyId *string `json:"accessKeyId,omitempty" xml:"accessKeyId,omitempty"` + // accesskey secret + AccessKeySecret *string `json:"accessKeySecret,omitempty" xml:"accessKeySecret,omitempty"` + // security token + SecurityToken *string `json:"securityToken,omitempty" xml:"securityToken,omitempty"` + // bearer token + BearerToken *string `json:"bearerToken,omitempty" xml:"bearerToken,omitempty"` + // type + Type *string `json:"type,omitempty" xml:"type,omitempty"` +} + +func (s CredentialModel) String() string { + return tea.Prettify(s) +} + +func (s CredentialModel) GoString() string { + return s.String() +} + +func (s *CredentialModel) SetAccessKeyId(v string) *CredentialModel { + s.AccessKeyId = &v + return s +} + +func (s *CredentialModel) SetAccessKeySecret(v string) *CredentialModel { + s.AccessKeySecret = &v + return s +} + +func (s *CredentialModel) SetSecurityToken(v string) *CredentialModel { + s.SecurityToken = &v + return s +} + +func (s *CredentialModel) SetBearerToken(v string) *CredentialModel { + s.BearerToken = &v + return s +} + +func (s *CredentialModel) SetType(v string) *CredentialModel { + s.Type = &v + return s +} diff --git a/vendor/github.com/aliyun/credentials-go/credentials/ecs_ram_role.go b/vendor/github.com/aliyun/credentials-go/credentials/ecs_ram_role.go index 5e7ddf4de..d86360fc5 100644 --- a/vendor/github.com/aliyun/credentials-go/credentials/ecs_ram_role.go +++ b/vendor/github.com/aliyun/credentials-go/credentials/ecs_ram_role.go @@ -40,6 +40,22 @@ func newEcsRAMRoleCredential(roleName string, inAdvanceScale float64, runtime *u } } +func (e *EcsRAMRoleCredential) GetCredential() (*CredentialModel, error) { + if e.sessionCredential == nil || e.needUpdateCredential() { + err := e.updateCredential() + if err != nil { + return nil, err + } + } + credential := &CredentialModel{ + AccessKeyId: tea.String(e.sessionCredential.AccessKeyId), + AccessKeySecret: tea.String(e.sessionCredential.AccessKeySecret), + SecurityToken: tea.String(e.sessionCredential.SecurityToken), + Type: tea.String("ecs_ram_role"), + } + return credential, nil +} + // GetAccessKeyId reutrns EcsRAMRoleCredential's AccessKeyId // if AccessKeyId is not exist or out of date, the function will update it. func (e *EcsRAMRoleCredential) GetAccessKeyId() (*string, error) { diff --git a/vendor/github.com/aliyun/credentials-go/credentials/oidc_credential.go b/vendor/github.com/aliyun/credentials-go/credentials/oidc_credential.go index 76192cbee..7d960abaf 100644 --- a/vendor/github.com/aliyun/credentials-go/credentials/oidc_credential.go +++ b/vendor/github.com/aliyun/credentials-go/credentials/oidc_credential.go @@ -55,6 +55,22 @@ func newOIDCRoleArnCredential(accessKeyId, accessKeySecret, roleArn, OIDCProvide } } +func (e *OIDCCredential) GetCredential() (*CredentialModel, error) { + if e.sessionCredential == nil || e.needUpdateCredential() { + err := e.updateCredential() + if err != nil { + return nil, err + } + } + credential := &CredentialModel{ + AccessKeyId: tea.String(e.sessionCredential.AccessKeyId), + AccessKeySecret: tea.String(e.sessionCredential.AccessKeySecret), + SecurityToken: tea.String(e.sessionCredential.SecurityToken), + Type: tea.String("oidc_role_arn"), + } + return credential, nil +} + // GetAccessKeyId reutrns OIDCCredential's AccessKeyId // if AccessKeyId is not exist or out of date, the function will update it. func (r *OIDCCredential) GetAccessKeyId() (*string, error) { @@ -123,6 +139,9 @@ func (r *OIDCCredential) updateCredential() (err error) { } request := request.NewCommonRequest() request.Domain = "sts.aliyuncs.com" + if r.runtime.STSEndpoint != "" { + request.Domain = r.runtime.STSEndpoint + } request.Scheme = "HTTPS" request.Method = "POST" request.QueryParams["Timestamp"] = utils.GetTimeInFormatISO8601() @@ -138,12 +157,6 @@ func (r *OIDCCredential) updateCredential() (err error) { request.QueryParams["RoleSessionName"] = r.RoleSessionName request.QueryParams["Version"] = "2015-04-01" request.QueryParams["SignatureNonce"] = utils.GetUUID() - if r.AccessKeyId != "" && r.AccessKeySecret != "" { - signature := utils.ShaHmac1(request.BuildStringToSign(), r.AccessKeySecret+"&") - request.QueryParams["Signature"] = signature - request.QueryParams["AccessKeyId"] = r.AccessKeyId - request.QueryParams["AccessKeySecret"] = r.AccessKeySecret - } request.Headers["Host"] = request.Domain request.Headers["Accept-Encoding"] = "identity" request.Headers["content-type"] = "application/x-www-form-urlencoded" diff --git a/vendor/github.com/aliyun/credentials-go/credentials/oidc_credential_provider.go b/vendor/github.com/aliyun/credentials-go/credentials/oidc_credential_provider.go new file mode 100644 index 000000000..928eb9315 --- /dev/null +++ b/vendor/github.com/aliyun/credentials-go/credentials/oidc_credential_provider.go @@ -0,0 +1,37 @@ +package credentials + +import ( + "os" + + "github.com/alibabacloud-go/tea/tea" +) + +type oidcCredentialsProvider struct{} + +var providerOIDC = new(oidcCredentialsProvider) + +func newOidcCredentialsProvider() Provider { + return &oidcCredentialsProvider{} +} + +func (p *oidcCredentialsProvider) resolve() (*Config, error) { + roleArn, ok1 := os.LookupEnv(ENVRoleArn) + oidcProviderArn, ok2 := os.LookupEnv(ENVOIDCProviderArn) + oidcTokenFilePath, ok3 := os.LookupEnv(ENVOIDCTokenFile) + if !ok1 || !ok2 || !ok3 { + return nil, nil + } + + config := &Config{ + Type: tea.String("oidc_role_arn"), + RoleArn: tea.String(roleArn), + OIDCProviderArn: tea.String(oidcProviderArn), + OIDCTokenFilePath: tea.String(oidcTokenFilePath), + RoleSessionName: tea.String("defaultSessionName"), + } + roleSessionName, ok := os.LookupEnv(ENVRoleSessionName) + if ok { + config.RoleSessionName = tea.String(roleSessionName) + } + return config, nil +} diff --git a/vendor/github.com/aliyun/credentials-go/credentials/profile_provider.go b/vendor/github.com/aliyun/credentials-go/credentials/profile_provider.go index d6292b035..de02c3dc4 100644 --- a/vendor/github.com/aliyun/credentials-go/credentials/profile_provider.go +++ b/vendor/github.com/aliyun/credentials-go/credentials/profile_provider.go @@ -46,10 +46,11 @@ func newProfileProvider(name ...string) Provider { func (p *profileProvider) resolve() (*Config, error) { path, ok := os.LookupEnv(ENVCredentialFile) if !ok { - path, err := checkDefaultPath() + defaultPath, err := checkDefaultPath() if err != nil { return nil, err } + path = defaultPath if path == "" { return nil, nil } diff --git a/vendor/github.com/aliyun/credentials-go/credentials/provider.go b/vendor/github.com/aliyun/credentials-go/credentials/provider.go index f9d4ae574..fe813db33 100644 --- a/vendor/github.com/aliyun/credentials-go/credentials/provider.go +++ b/vendor/github.com/aliyun/credentials-go/credentials/provider.go @@ -5,6 +5,10 @@ const ( ENVCredentialFile = "ALIBABA_CLOUD_CREDENTIALS_FILE" ENVEcsMetadata = "ALIBABA_CLOUD_ECS_METADATA" PATHCredentialFile = "~/.alibabacloud/credentials" + ENVRoleArn = "ALIBABA_CLOUD_ROLE_ARN" + ENVOIDCProviderArn = "ALIBABA_CLOUD_OIDC_PROVIDER_ARN" + ENVOIDCTokenFile = "ALIBABA_CLOUD_OIDC_TOKEN_FILE" + ENVRoleSessionName = "ALIBABA_CLOUD_ROLE_SESSION_NAME" ) // Provider will be implemented When you want to customize the provider. diff --git a/vendor/github.com/aliyun/credentials-go/credentials/provider_chain.go b/vendor/github.com/aliyun/credentials-go/credentials/provider_chain.go index 2764a701c..a694d5cb5 100644 --- a/vendor/github.com/aliyun/credentials-go/credentials/provider_chain.go +++ b/vendor/github.com/aliyun/credentials-go/credentials/provider_chain.go @@ -8,7 +8,7 @@ type providerChain struct { Providers []Provider } -var defaultproviders = []Provider{providerEnv, providerProfile, providerInstance} +var defaultproviders = []Provider{providerEnv, providerOIDC, providerProfile, providerInstance} var defaultChain = newProviderChain(defaultproviders) func newProviderChain(providers []Provider) Provider { diff --git a/vendor/github.com/aliyun/credentials-go/credentials/rsa_key_pair_credential.go b/vendor/github.com/aliyun/credentials-go/credentials/rsa_key_pair_credential.go index 3e4310eca..82988eca0 100644 --- a/vendor/github.com/aliyun/credentials-go/credentials/rsa_key_pair_credential.go +++ b/vendor/github.com/aliyun/credentials-go/credentials/rsa_key_pair_credential.go @@ -42,6 +42,22 @@ func newRsaKeyPairCredential(privateKey, publicKeyId string, sessionExpiration i } } +func (e *RsaKeyPairCredential) GetCredential() (*CredentialModel, error) { + if e.sessionCredential == nil || e.needUpdateCredential() { + err := e.updateCredential() + if err != nil { + return nil, err + } + } + credential := &CredentialModel{ + AccessKeyId: tea.String(e.sessionCredential.AccessKeyId), + AccessKeySecret: tea.String(e.sessionCredential.AccessKeySecret), + SecurityToken: tea.String(e.sessionCredential.SecurityToken), + Type: tea.String("rsa_key_pair"), + } + return credential, nil +} + // GetAccessKeyId reutrns RsaKeyPairCredential's AccessKeyId // if AccessKeyId is not exist or out of date, the function will update it. func (r *RsaKeyPairCredential) GetAccessKeyId() (*string, error) { @@ -89,6 +105,8 @@ func (r *RsaKeyPairCredential) updateCredential() (err error) { request.Domain = "sts.aliyuncs.com" if r.runtime.Host != "" { request.Domain = r.runtime.Host + } else if r.runtime.STSEndpoint != "" { + request.Domain = r.runtime.STSEndpoint } request.Scheme = "HTTPS" request.Method = "GET" diff --git a/vendor/github.com/aliyun/credentials-go/credentials/sts_credential.go b/vendor/github.com/aliyun/credentials-go/credentials/sts_credential.go index ba07dab49..5a9973f21 100644 --- a/vendor/github.com/aliyun/credentials-go/credentials/sts_credential.go +++ b/vendor/github.com/aliyun/credentials-go/credentials/sts_credential.go @@ -17,6 +17,16 @@ func newStsTokenCredential(accessKeyId, accessKeySecret, securityToken string) * } } +func (s *StsTokenCredential) GetCredential() (*CredentialModel, error) { + credential := &CredentialModel{ + AccessKeyId: tea.String(s.AccessKeyId), + AccessKeySecret: tea.String(s.AccessKeySecret), + SecurityToken: tea.String(s.SecurityToken), + Type: tea.String("sts"), + } + return credential, nil +} + // GetAccessKeyId reutrns StsTokenCredential's AccessKeyId func (s *StsTokenCredential) GetAccessKeyId() (*string, error) { return tea.String(s.AccessKeyId), nil diff --git a/vendor/github.com/aliyun/credentials-go/credentials/sts_role_arn_credential.go b/vendor/github.com/aliyun/credentials-go/credentials/sts_role_arn_credential.go index f31ba1e32..3ddf32fa2 100644 --- a/vendor/github.com/aliyun/credentials-go/credentials/sts_role_arn_credential.go +++ b/vendor/github.com/aliyun/credentials-go/credentials/sts_role_arn_credential.go @@ -23,6 +23,7 @@ type RAMRoleArnCredential struct { RoleSessionName string RoleSessionExpiration int Policy string + ExternalId string sessionCredential *sessionCredential runtime *utils.Runtime } @@ -51,6 +52,36 @@ func newRAMRoleArnCredential(accessKeyId, accessKeySecret, roleArn, roleSessionN } } +func newRAMRoleArnWithExternalIdCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName, policy string, roleSessionExpiration int, externalId string, runtime *utils.Runtime) *RAMRoleArnCredential { + return &RAMRoleArnCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + RoleArn: roleArn, + RoleSessionName: roleSessionName, + RoleSessionExpiration: roleSessionExpiration, + Policy: policy, + ExternalId: externalId, + credentialUpdater: new(credentialUpdater), + runtime: runtime, + } +} + +func (e *RAMRoleArnCredential) GetCredential() (*CredentialModel, error) { + if e.sessionCredential == nil || e.needUpdateCredential() { + err := e.updateCredential() + if err != nil { + return nil, err + } + } + credential := &CredentialModel{ + AccessKeyId: tea.String(e.sessionCredential.AccessKeyId), + AccessKeySecret: tea.String(e.sessionCredential.AccessKeySecret), + SecurityToken: tea.String(e.sessionCredential.SecurityToken), + Type: tea.String("ram_role_arn"), + } + return credential, nil +} + // GetAccessKeyId reutrns RamRoleArnCredential's AccessKeyId // if AccessKeyId is not exist or out of date, the function will update it. func (r *RAMRoleArnCredential) GetAccessKeyId() (*string, error) { @@ -103,6 +134,9 @@ func (r *RAMRoleArnCredential) updateCredential() (err error) { } request := request.NewCommonRequest() request.Domain = "sts.aliyuncs.com" + if r.runtime.STSEndpoint != "" { + request.Domain = r.runtime.STSEndpoint + } request.Scheme = "HTTPS" request.Method = "GET" request.QueryParams["AccessKeyId"] = r.AccessKeyId @@ -122,6 +156,9 @@ func (r *RAMRoleArnCredential) updateCredential() (err error) { if r.Policy != "" { request.QueryParams["Policy"] = r.Policy } + if r.ExternalId != "" { + request.QueryParams["ExternalId"] = r.ExternalId + } request.QueryParams["RoleSessionName"] = r.RoleSessionName request.QueryParams["SignatureMethod"] = "HMAC-SHA1" request.QueryParams["SignatureVersion"] = "1.0" diff --git a/vendor/github.com/aliyun/credentials-go/credentials/uri_credential.go b/vendor/github.com/aliyun/credentials-go/credentials/uri_credential.go index e8f303fc7..d03006c9c 100644 --- a/vendor/github.com/aliyun/credentials-go/credentials/uri_credential.go +++ b/vendor/github.com/aliyun/credentials-go/credentials/uri_credential.go @@ -37,6 +37,22 @@ func newURLCredential(URL string) *URLCredential { } } +func (e *URLCredential) GetCredential() (*CredentialModel, error) { + if e.sessionCredential == nil || e.needUpdateCredential() { + err := e.updateCredential() + if err != nil { + return nil, err + } + } + credential := &CredentialModel{ + AccessKeyId: tea.String(e.sessionCredential.AccessKeyId), + AccessKeySecret: tea.String(e.sessionCredential.AccessKeySecret), + SecurityToken: tea.String(e.sessionCredential.SecurityToken), + Type: tea.String("credential_uri"), + } + return credential, nil +} + // GetAccessKeyId reutrns URLCredential's AccessKeyId // if AccessKeyId is not exist or out of date, the function will update it. func (e *URLCredential) GetAccessKeyId() (*string, error) { diff --git a/vendor/github.com/aliyun/credentials-go/credentials/utils/runtime.go b/vendor/github.com/aliyun/credentials-go/credentials/utils/runtime.go index d4a27c9cd..432395cf4 100644 --- a/vendor/github.com/aliyun/credentials-go/credentials/utils/runtime.go +++ b/vendor/github.com/aliyun/credentials-go/credentials/utils/runtime.go @@ -12,6 +12,7 @@ type Runtime struct { ConnectTimeout int Proxy string Host string + STSEndpoint string } // NewRuntime returns a Runtime diff --git a/vendor/github.com/aws/aws-sdk-go-v2/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/CHANGELOG.md index c3512dd7a..1f4384c96 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/CHANGELOG.md @@ -1,3 +1,1617 @@ +# Release (2023-10-12) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2`: v1.21.2 + * **Bug Fix**: Improve recognition of retryable DNS errors. +* `github.com/aws/aws-sdk-go-v2/config`: [v1.18.45](config/CHANGELOG.md#v11845-2023-10-12) + * **Bug Fix**: Fail to load config if an explicitly provided profile doesn't exist. +* `github.com/aws/aws-sdk-go-v2/service/auditmanager`: [v1.27.0](service/auditmanager/CHANGELOG.md#v1270-2023-10-12) + * **Feature**: This release introduces a new limit to the awsAccounts parameter. When you create or update an assessment, there is now a limit of 200 AWS accounts that can be specified in the assessment scope. +* `github.com/aws/aws-sdk-go-v2/service/autoscaling`: [v1.31.0](service/autoscaling/CHANGELOG.md#v1310-2023-10-12) + * **Feature**: Update the NotificationMetadata field to only allow visible ascii characters. Add paginators to DescribeInstanceRefreshes, DescribeLoadBalancers, and DescribeLoadBalancerTargetGroups +* `github.com/aws/aws-sdk-go-v2/service/configservice`: [v1.37.0](service/configservice/CHANGELOG.md#v1370-2023-10-12) + * **Feature**: Add enums for resource types supported by Config +* `github.com/aws/aws-sdk-go-v2/service/controltower`: [v1.4.0](service/controltower/CHANGELOG.md#v140-2023-10-12) + * **Feature**: Added new EnabledControl resource details to ListEnabledControls API and added new GetEnabledControl API. +* `github.com/aws/aws-sdk-go-v2/service/customerprofiles`: [v1.29.0](service/customerprofiles/CHANGELOG.md#v1290-2023-10-12) + * **Feature**: Adds sensitive trait to various shapes in Customer Profiles Calculated Attribute API model. +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.125.0](service/ec2/CHANGELOG.md#v11250-2023-10-12) + * **Feature**: This release adds Ubuntu Pro as a supported platform for On-Demand Capacity Reservations and adds support for setting an Amazon Machine Image (AMI) to disabled state. Disabling the AMI makes it private if it was previously shared, and prevents new EC2 instance launches from it. +* `github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2`: [v1.21.6](service/elasticloadbalancingv2/CHANGELOG.md#v1216-2023-10-12) + * **Documentation**: This release enables routing policies with Availability Zone affinity for Network Load Balancers. +* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.63.0](service/glue/CHANGELOG.md#v1630-2023-10-12) + * **Feature**: Extending version control support to GitLab and Bitbucket from AWSGlue +* `github.com/aws/aws-sdk-go-v2/service/inspector2`: [v1.17.0](service/inspector2/CHANGELOG.md#v1170-2023-10-12) + * **Feature**: Add MacOs ec2 platform support +* `github.com/aws/aws-sdk-go-v2/service/ivsrealtime`: [v1.5.0](service/ivsrealtime/CHANGELOG.md#v150-2023-10-12) + * **Feature**: Update GetParticipant to return additional metadata. +* `github.com/aws/aws-sdk-go-v2/service/lambda`: [v1.40.0](service/lambda/CHANGELOG.md#v1400-2023-10-12) + * **Feature**: Adds support for Lambda functions to access Dual-Stack subnets over IPv6, via an opt-in flag in CreateFunction and UpdateFunctionConfiguration APIs +* `github.com/aws/aws-sdk-go-v2/service/location`: [v1.28.0](service/location/CHANGELOG.md#v1280-2023-10-12) + * **Feature**: This release adds endpoint updates for all AWS Location resource operations. +* `github.com/aws/aws-sdk-go-v2/service/machinelearning`: [v1.18.0](service/machinelearning/CHANGELOG.md#v1180-2023-10-12) + * **Feature**: This release marks Password field as sensitive +* `github.com/aws/aws-sdk-go-v2/service/pricing`: [v1.21.9](service/pricing/CHANGELOG.md#v1219-2023-10-12) + * **Documentation**: Documentation updates for Price List +* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.56.0](service/rds/CHANGELOG.md#v1560-2023-10-12) + * **Feature**: This release adds support for adding a dedicated log volume to open-source RDS instances. +* `github.com/aws/aws-sdk-go-v2/service/rekognition`: [v1.31.0](service/rekognition/CHANGELOG.md#v1310-2023-10-12) + * **Feature**: Amazon Rekognition introduces support for Custom Moderation. This allows the enhancement of accuracy for detect moderation labels operations by creating custom adapters tuned on customer data. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.111.0](service/sagemaker/CHANGELOG.md#v11110-2023-10-12) + * **Feature**: Amazon SageMaker Canvas adds KendraSettings and DirectDeploySettings support for CanvasAppSettings +* `github.com/aws/aws-sdk-go-v2/service/textract`: [v1.25.0](service/textract/CHANGELOG.md#v1250-2023-10-12) + * **Feature**: This release adds 9 new APIs for adapter and adapter version management, 3 new APIs for tagging, and updates AnalyzeDocument and StartDocumentAnalysis API parameters for using adapters. +* `github.com/aws/aws-sdk-go-v2/service/transcribe`: [v1.29.0](service/transcribe/CHANGELOG.md#v1290-2023-10-12) + * **Feature**: This release is to enable m4a format to customers +* `github.com/aws/aws-sdk-go-v2/service/workspaces`: [v1.31.2](service/workspaces/CHANGELOG.md#v1312-2023-10-12) + * **Documentation**: Updated the CreateWorkspaces action documentation to clarify that the PCoIP protocol is only available for Windows bundles. + +# Release (2023-10-06) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.124.0](service/ec2/CHANGELOG.md#v11240-2023-10-06) + * **Feature**: Documentation updates for Elastic Compute Cloud (EC2). +* `github.com/aws/aws-sdk-go-v2/service/fsx`: [v1.33.0](service/fsx/CHANGELOG.md#v1330-2023-10-06) + * **Feature**: After performing steps to repair the Active Directory configuration of a file system, use this action to initiate the process of attempting to recover to the file system. +* `github.com/aws/aws-sdk-go-v2/service/marketplacecatalog`: [v1.18.0](service/marketplacecatalog/CHANGELOG.md#v1180-2023-10-06) + * **Feature**: This release adds support for Document type as an alternative for stringified JSON for StartChangeSet, DescribeChangeSet and DescribeEntity APIs +* `github.com/aws/aws-sdk-go-v2/service/quicksight`: [v1.45.0](service/quicksight/CHANGELOG.md#v1450-2023-10-06) + * **Feature**: NullOption in FilterListConfiguration; Dataset schema/table max length increased; Support total placement for pivot table visual; Lenient mode relaxes the validation to create resources with definition; Data sources can be added to folders; Redshift data sources support IAM Role-based authentication +* `github.com/aws/aws-sdk-go-v2/service/transfer`: [v1.34.0](service/transfer/CHANGELOG.md#v1340-2023-10-06) + * **Feature**: This release updates the max character limit of PreAuthenticationLoginBanner and PostAuthenticationLoginBanner to 4096 characters + +# Release (2023-10-05) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/omics`: [v1.10.0](service/omics/CHANGELOG.md#v1100-2023-10-05) + * **Feature**: Add Etag Support for Omics Storage in ListReadSets and GetReadSetMetadata API +* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.55.1](service/rds/CHANGELOG.md#v1551-2023-10-05) + * **Documentation**: Updates Amazon RDS documentation for corrections and minor improvements. +* `github.com/aws/aws-sdk-go-v2/service/route53`: [v1.30.0](service/route53/CHANGELOG.md#v1300-2023-10-05) + * **Feature**: Add hostedzonetype filter to ListHostedZones API. +* `github.com/aws/aws-sdk-go-v2/service/securityhub`: [v1.37.0](service/securityhub/CHANGELOG.md#v1370-2023-10-05) + * **Feature**: Added new resource detail objects to ASFF, including resources for AwsEventsEventbus, AwsEventsEndpoint, AwsDmsEndpoint, AwsDmsReplicationTask, AwsDmsReplicationInstance, AwsRoute53HostedZone, and AwsMskCluster +* `github.com/aws/aws-sdk-go-v2/service/storagegateway`: [v1.21.0](service/storagegateway/CHANGELOG.md#v1210-2023-10-05) + * **Feature**: Add SoftwareVersion to response of DescribeGatewayInformation. +* `github.com/aws/aws-sdk-go-v2/service/workspaces`: [v1.31.0](service/workspaces/CHANGELOG.md#v1310-2023-10-05) + * **Feature**: This release introduces Manage applications. This feature allows users to manage their WorkSpaces applications by associating or disassociating their WorkSpaces with applications. The DescribeWorkspaces API will now additionally return OperatingSystemName in its responses. + +# Release (2023-10-04) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/appconfig`: [v1.21.0](service/appconfig/CHANGELOG.md#v1210-2023-10-04) + * **Feature**: AWS AppConfig introduces KMS customer-managed key (CMK) encryption support for data saved to AppConfig's hosted configuration store. +* `github.com/aws/aws-sdk-go-v2/service/datazone`: [v1.0.0](service/datazone/CHANGELOG.md#v100-2023-10-04) + * **Release**: New AWS service client module + * **Feature**: Initial release of Amazon DataZone +* `github.com/aws/aws-sdk-go-v2/service/mediatailor`: [v1.28.0](service/mediatailor/CHANGELOG.md#v1280-2023-10-04) + * **Feature**: Updates DescribeVodSource to include a list of ad break opportunities in the response +* `github.com/aws/aws-sdk-go-v2/service/mgn`: [v1.21.0](service/mgn/CHANGELOG.md#v1210-2023-10-04) + * **Feature**: This release includes the following new APIs: ListConnectors, CreateConnector, UpdateConnector, DeleteConnector and UpdateSourceServer to support the source action framework feature. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.110.0](service/sagemaker/CHANGELOG.md#v11100-2023-10-04) + * **Feature**: Adding support for AdditionalS3DataSource, a data source used for training or inference that is in addition to the input dataset or model data. + +# Release (2023-10-03) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.69.0](service/connect/CHANGELOG.md#v1690-2023-10-03) + * **Feature**: GetMetricDataV2 API: Update to include new metrics CONTACTS_RESOLVED_IN_X , AVG_HOLD_TIME_ALL_CONTACTS , AVG_RESOLUTION_TIME , ABANDONMENT_RATE , AGENT_NON_RESPONSE_WITHOUT_CUSTOMER_ABANDONS with added features: Interval Period, TimeZone, Negate MetricFilters, Extended date time range. +* `github.com/aws/aws-sdk-go-v2/service/location`: [v1.27.0](service/location/CHANGELOG.md#v1270-2023-10-03) + * **Feature**: Amazon Location Service adds support for bounding polygon queries. Additionally, the GeofenceCount field has been added to the DescribeGeofenceCollection API response. +* `github.com/aws/aws-sdk-go-v2/service/mediaconvert`: [v1.43.0](service/mediaconvert/CHANGELOG.md#v1430-2023-10-03) + * **Feature**: This release adds the ability to replace video frames without modifying the audio essence. +* `github.com/aws/aws-sdk-go-v2/service/oam`: [v1.4.0](service/oam/CHANGELOG.md#v140-2023-10-03) + * **Feature**: This release adds support for sharing AWS::ApplicationInsights::Application resources. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.109.0](service/sagemaker/CHANGELOG.md#v11090-2023-10-03) + * **Feature**: This release allows users to run Selective Execution in SageMaker Pipelines without SourcePipelineExecutionArn if selected steps do not have any dependent steps. +* `github.com/aws/aws-sdk-go-v2/service/wellarchitected`: [v1.23.0](service/wellarchitected/CHANGELOG.md#v1230-2023-10-03) + * **Feature**: AWS Well-Architected now supports Review Templates that allows you to create templates with pre-filled answers for Well-Architected and Custom Lens best practices. + +# Release (2023-10-02) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/bedrock`: [v1.1.0](service/bedrock/CHANGELOG.md#v110-2023-10-02) + * **Feature**: Provisioned throughput feature with Amazon and third-party base models, and update validators for model identifier and taggable resource ARNs. +* `github.com/aws/aws-sdk-go-v2/service/bedrockruntime`: [v1.1.0](service/bedrockruntime/CHANGELOG.md#v110-2023-10-02) + * **Feature**: Add model timeout exception for InvokeModelWithResponseStream API and update validator for invoke model identifier. +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.123.0](service/ec2/CHANGELOG.md#v11230-2023-10-02) + * **Feature**: Introducing Amazon EC2 R7iz instances with 3.9 GHz sustained all-core turbo frequency and deliver up to 20% better performance than previous generation z1d instances. +* `github.com/aws/aws-sdk-go-v2/service/managedblockchain`: [v1.16.6](service/managedblockchain/CHANGELOG.md#v1166-2023-10-02) + * **Documentation**: Remove Rinkeby as option from Ethereum APIs +* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.55.0](service/rds/CHANGELOG.md#v1550-2023-10-02) + * **Feature**: Adds DefaultCertificateForNewLaunches field in the DescribeCertificates API response. +* `github.com/aws/aws-sdk-go-v2/service/sso`: [v1.15.0](service/sso/CHANGELOG.md#v1150-2023-10-02) + * **Feature**: Fix FIPS Endpoints in aws-us-gov. +* `github.com/aws/aws-sdk-go-v2/service/sts`: [v1.23.0](service/sts/CHANGELOG.md#v1230-2023-10-02) + * **Feature**: STS API updates for assumeRole +* `github.com/aws/aws-sdk-go-v2/service/transfer`: [v1.33.9](service/transfer/CHANGELOG.md#v1339-2023-10-02) + * **Documentation**: Documentation updates for AWS Transfer Family + +# Release (2023-09-28) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/bedrock`: [v1.0.0](service/bedrock/CHANGELOG.md#v100-2023-09-28) + * **Release**: New AWS service client module + * **Feature**: Model Invocation logging added to enable or disable logs in customer account. Model listing and description support added. Provisioned Throughput feature added. Custom model support added for creating custom models. Also includes list, and delete functions for custom model. +* `github.com/aws/aws-sdk-go-v2/service/bedrockruntime`: [v1.0.0](service/bedrockruntime/CHANGELOG.md#v100-2023-09-28) + * **Release**: New AWS service client module + * **Feature**: Run Inference: Added support to run the inference on models. Includes set of APIs for running inference in streaming and non-streaming mode. +* `github.com/aws/aws-sdk-go-v2/service/budgets`: [v1.17.0](service/budgets/CHANGELOG.md#v1170-2023-09-28) + * **Feature**: Update DescribeBudgets and DescribeBudgetNotificationsForAccount MaxResults limit to 1000. +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.122.0](service/ec2/CHANGELOG.md#v11220-2023-09-28) + * **Feature**: Adds support for Customer Managed Key encryption for Amazon Verified Access resources +* `github.com/aws/aws-sdk-go-v2/service/iotfleetwise`: [v1.6.0](service/iotfleetwise/CHANGELOG.md#v160-2023-09-28) + * **Feature**: AWS IoT FleetWise now supports encryption through a customer managed AWS KMS key. The PutEncryptionConfiguration and GetEncryptionConfiguration APIs were added. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.108.0](service/sagemaker/CHANGELOG.md#v11080-2023-09-28) + * **Feature**: Online store feature groups supports Standard and InMemory tier storage types for low latency storage for real-time data retrieval. The InMemory tier supports collection types List, Set, and Vector. +* `github.com/aws/aws-sdk-go-v2/service/sagemakerfeaturestoreruntime`: [v1.18.0](service/sagemakerfeaturestoreruntime/CHANGELOG.md#v1180-2023-09-28) + * **Feature**: Feature Store supports read/write of records with collection type features. +* `github.com/aws/aws-sdk-go-v2/service/wafv2`: [v1.39.1](service/wafv2/CHANGELOG.md#v1391-2023-09-28) + * **Documentation**: Correct and improve the documentation for the FieldToMatch option JA3 fingerprint. + +# Release (2023-09-27) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider`: [v1.27.0](service/cognitoidentityprovider/CHANGELOG.md#v1270-2023-09-27) + * **Feature**: The UserPoolType Status field is no longer used. +* `github.com/aws/aws-sdk-go-v2/service/firehose`: [v1.19.0](service/firehose/CHANGELOG.md#v1190-2023-09-27) + * **Feature**: Features : Adding support for new data ingestion source to Kinesis Firehose - AWS Managed Services Kafka. +* `github.com/aws/aws-sdk-go-v2/service/iot`: [v1.40.0](service/iot/CHANGELOG.md#v1400-2023-09-27) + * **Feature**: Added support for IoT Rules Engine Kafka Action Headers +* `github.com/aws/aws-sdk-go-v2/service/textract`: [v1.24.0](service/textract/CHANGELOG.md#v1240-2023-09-27) + * **Feature**: This release adds new feature - Layout to Analyze Document API which can automatically extract layout elements such as titles, paragraphs, headers, section headers, lists, page numbers, footers, table areas, key-value areas and figure areas and order the elements as a human would read. + +# Release (2023-09-26) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/appintegrations`: [v1.18.0](service/appintegrations/CHANGELOG.md#v1180-2023-09-26) + * **Feature**: The Amazon AppIntegrations service adds a set of APIs (in preview) to manage third party applications to be used in Amazon Connect agent workspace. +* `github.com/aws/aws-sdk-go-v2/service/apprunner`: [v1.21.0](service/apprunner/CHANGELOG.md#v1210-2023-09-26) + * **Feature**: This release allows an App Runner customer to specify a custom source directory to run the build & start command. This change allows App Runner to support monorepo based repositories +* `github.com/aws/aws-sdk-go-v2/service/codedeploy`: [v1.18.1](service/codedeploy/CHANGELOG.md#v1181-2023-09-26) + * **Documentation**: CodeDeploy now supports In-place and Blue/Green EC2 deployments with multiple Classic Load Balancers and multiple Target Groups. +* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.68.0](service/connect/CHANGELOG.md#v1680-2023-09-26) + * **Feature**: This release updates a set of Amazon Connect APIs that provides the ability to integrate third party applications in the Amazon Connect agent workspace. +* `github.com/aws/aws-sdk-go-v2/service/dynamodb`: [v1.22.0](service/dynamodb/CHANGELOG.md#v1220-2023-09-26) + * **Feature**: Amazon DynamoDB now supports Incremental Export as an enhancement to the existing Export Table +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.121.0](service/ec2/CHANGELOG.md#v11210-2023-09-26) + * **Feature**: The release includes AWS verified access to support FIPs compliance in North America regions +* `github.com/aws/aws-sdk-go-v2/service/lakeformation`: [v1.24.0](service/lakeformation/CHANGELOG.md#v1240-2023-09-26) + * **Feature**: This release adds three new API support "CreateLakeFormationOptIn", "DeleteLakeFormationOptIn" and "ListLakeFormationOptIns", and also updates the corresponding documentation. +* `github.com/aws/aws-sdk-go-v2/service/pinpoint`: [v1.22.6](service/pinpoint/CHANGELOG.md#v1226-2023-09-26) + * **Documentation**: Update documentation for RemoveAttributes to more accurately reflect its behavior when attributes are deleted. +* `github.com/aws/aws-sdk-go-v2/service/s3`: [v1.40.0](service/s3/CHANGELOG.md#v1400-2023-09-26) + * **Feature**: This release adds a new field COMPLETED to the ReplicationStatus Enum. You can now use this field to validate the replication status of S3 objects using the AWS SDK. + +# Release (2023-09-25) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/amplifyuibuilder`: [v1.13.0](service/amplifyuibuilder/CHANGELOG.md#v1130-2023-09-25) + * **Feature**: Support for generating code that is compatible with future versions of amplify project dependencies. +* `github.com/aws/aws-sdk-go-v2/service/chimesdkmediapipelines`: [v1.9.0](service/chimesdkmediapipelines/CHANGELOG.md#v190-2023-09-25) + * **Feature**: Adds support for sending WebRTC audio to Amazon Kineses Video Streams. +* `github.com/aws/aws-sdk-go-v2/service/emrserverless`: [v1.11.0](service/emrserverless/CHANGELOG.md#v1110-2023-09-25) + * **Feature**: This release adds support for application-wide default job configurations. +* `github.com/aws/aws-sdk-go-v2/service/finspacedata`: [v1.17.0](service/finspacedata/CHANGELOG.md#v1170-2023-09-25) + * **Feature**: Adding sensitive trait to attributes. Change max SessionDuration from 720 to 60. Correct "ApiAccess" attribute to "apiAccess" to maintain consistency between APIs. +* `github.com/aws/aws-sdk-go-v2/service/quicksight`: [v1.44.0](service/quicksight/CHANGELOG.md#v1440-2023-09-25) + * **Feature**: Added ability to tag users upon creation. +* `github.com/aws/aws-sdk-go-v2/service/ssm`: [v1.38.0](service/ssm/CHANGELOG.md#v1380-2023-09-25) + * **Feature**: This release updates the enum values for ResourceType in SSM DescribeInstanceInformation input and ConnectionStatus in GetConnectionStatus output. +* `github.com/aws/aws-sdk-go-v2/service/wafv2`: [v1.39.0](service/wafv2/CHANGELOG.md#v1390-2023-09-25) + * **Feature**: You can now perform an exact match against the web request's JA3 fingerprint. + +# Release (2023-09-22) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/config`: [v1.18.42](config/CHANGELOG.md#v11842-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. +* `github.com/aws/aws-sdk-go-v2/internal/ini`: [v1.3.43](internal/ini/CHANGELOG.md#v1343-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. +* `github.com/aws/aws-sdk-go-v2/service/braket`: [v1.20.0](service/braket/CHANGELOG.md#v1200-2023-09-22) + * **Feature**: This release adds support to view the device queue depth (the number of queued quantum tasks and hybrid jobs on a device) and queue position for a quantum task and hybrid job. +* `github.com/aws/aws-sdk-go-v2/service/cloudwatchevents`: [v1.18.0](service/cloudwatchevents/CHANGELOG.md#v1180-2023-09-22) + * **Feature**: Adds sensitive trait to various shapes in Jetstream Connections API model. +* `github.com/aws/aws-sdk-go-v2/service/databasemigrationservice`: [v1.31.0](service/databasemigrationservice/CHANGELOG.md#v1310-2023-09-22) + * **Feature**: new vendors for DMS CSF: MongoDB, MariaDB, DocumentDb and Redshift +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.120.0](service/ec2/CHANGELOG.md#v11200-2023-09-22) + * **Feature**: EC2 M2 Pro Mac instances are powered by Apple M2 Pro Mac Mini computers featuring 12 core CPU, 19 core GPU, 32 GiB of memory, and 16 core Apple Neural Engine and uniquely enabled by the AWS Nitro System through high-speed Thunderbolt connections. +* `github.com/aws/aws-sdk-go-v2/service/efs`: [v1.21.7](service/efs/CHANGELOG.md#v1217-2023-09-22) + * **Documentation**: Documentation updates for Elastic File System +* `github.com/aws/aws-sdk-go-v2/service/guardduty`: [v1.28.0](service/guardduty/CHANGELOG.md#v1280-2023-09-22) + * **Feature**: Add `EKS_CLUSTER_NAME` to filter and sort key. +* `github.com/aws/aws-sdk-go-v2/service/mediaconvert`: [v1.42.0](service/mediaconvert/CHANGELOG.md#v1420-2023-09-22) + * **Feature**: This release supports the creation of of audio-only tracks in CMAF output groups. + +# Release (2023-09-20) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/appconfig`: [v1.20.0](service/appconfig/CHANGELOG.md#v1200-2023-09-20) + * **Feature**: Enabling boto3 paginators for list APIs and adding documentation around ServiceQuotaExceededException errors +* `github.com/aws/aws-sdk-go-v2/service/apprunner`: [v1.20.0](service/apprunner/CHANGELOG.md#v1200-2023-09-20) + * **Feature**: This release adds improvements for managing App Runner auto scaling configuration resources. New APIs: UpdateDefaultAutoScalingConfiguration and ListServicesForAutoScalingConfiguration. Updated API: DeleteAutoScalingConfiguration. +* `github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs`: [v1.24.0](service/cloudwatchlogs/CHANGELOG.md#v1240-2023-09-20) + * **Feature**: Add ClientToken to QueryDefinition CFN Handler in CWL +* `github.com/aws/aws-sdk-go-v2/service/codeartifact`: [v1.20.0](service/codeartifact/CHANGELOG.md#v1200-2023-09-20) + * **Feature**: Add support for the Swift package format. +* `github.com/aws/aws-sdk-go-v2/service/kinesisvideo`: [v1.18.4](service/kinesisvideo/CHANGELOG.md#v1184-2023-09-20) + * **Documentation**: Updated DescribeMediaStorageConfiguration, StartEdgeConfigurationUpdate, ImageGenerationConfiguration$SamplingInterval, and UpdateMediaStorageConfiguration to match AWS Docs. +* `github.com/aws/aws-sdk-go-v2/service/s3`: [v1.39.0](service/s3/CHANGELOG.md#v1390-2023-09-20) + * **Feature**: Fix an issue where the SDK can fail to unmarshall response due to NumberFormatException +* `github.com/aws/aws-sdk-go-v2/service/servicediscovery`: [v1.24.0](service/servicediscovery/CHANGELOG.md#v1240-2023-09-20) + * **Feature**: Adds a new DiscoverInstancesRevision API and also adds InstanceRevision field to the DiscoverInstances API response. +* `github.com/aws/aws-sdk-go-v2/service/ssooidc`: [v1.17.0](service/ssooidc/CHANGELOG.md#v1170-2023-09-20) + * **Feature**: Update FIPS endpoints in aws-us-gov. + +# Release (2023-09-19) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.119.0](service/ec2/CHANGELOG.md#v11190-2023-09-19) + * **Feature**: This release adds support for C7i, and R7a instance types. +* `github.com/aws/aws-sdk-go-v2/service/outposts`: [v1.30.0](service/outposts/CHANGELOG.md#v1300-2023-09-19) + * **Feature**: This release adds the InstanceFamilies field to the ListAssets response. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.107.0](service/sagemaker/CHANGELOG.md#v11070-2023-09-19) + * **Feature**: This release adds support for one-time model monitoring schedules that are executed immediately without delay, explicit data analysis windows for model monitoring schedules and exclude features attributes to remove features from model monitor analysis. + +# Release (2023-09-18) + +## General Highlights +* **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. +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/accessanalyzer`: [v1.21.0](service/accessanalyzer/CHANGELOG.md#v1210-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/acm`: [v1.19.0](service/acm/CHANGELOG.md#v1190-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/amplify`: [v1.15.0](service/amplify/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/apigatewaymanagementapi`: [v1.13.0](service/apigatewaymanagementapi/CHANGELOG.md#v1130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/appconfig`: [v1.19.0](service/appconfig/CHANGELOG.md#v1190-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/appconfigdata`: [v1.8.0](service/appconfigdata/CHANGELOG.md#v180-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/appfabric`: [v1.2.0](service/appfabric/CHANGELOG.md#v120-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/appintegrations`: [v1.17.0](service/appintegrations/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/applicationcostprofiler`: [v1.12.0](service/applicationcostprofiler/CHANGELOG.md#v1120-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/appmesh`: [v1.19.0](service/appmesh/CHANGELOG.md#v1190-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/arczonalshift`: [v1.3.0](service/arczonalshift/CHANGELOG.md#v130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/autoscalingplans`: [v1.15.0](service/autoscalingplans/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/backupgateway`: [v1.11.0](service/backupgateway/CHANGELOG.md#v1110-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/backupstorage`: [v1.3.0](service/backupstorage/CHANGELOG.md#v130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/braket`: [v1.19.0](service/braket/CHANGELOG.md#v1190-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/chimesdkvoice`: [v1.9.0](service/chimesdkvoice/CHANGELOG.md#v190-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/clouddirectory`: [v1.15.0](service/clouddirectory/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/cloudhsmv2`: [v1.16.0](service/cloudhsmv2/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/cloudsearch`: [v1.16.0](service/cloudsearch/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/cloudsearchdomain`: [v1.14.0](service/cloudsearchdomain/CHANGELOG.md#v1140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/cloudtraildata`: [v1.2.0](service/cloudtraildata/CHANGELOG.md#v120-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/codebuild`: [v1.22.0](service/codebuild/CHANGELOG.md#v1220-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/codedeploy`: [v1.18.0](service/codedeploy/CHANGELOG.md#v1180-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/codeguruprofiler`: [v1.15.0](service/codeguruprofiler/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/codegurureviewer`: [v1.19.0](service/codegurureviewer/CHANGELOG.md#v1190-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/codegurusecurity`: [v1.2.0](service/codegurusecurity/CHANGELOG.md#v120-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/codestar`: [v1.15.0](service/codestar/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/codestarnotifications`: [v1.16.0](service/codestarnotifications/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/cognitoidentity`: [v1.17.0](service/cognitoidentity/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/cognitosync`: [v1.14.0](service/cognitosync/CHANGELOG.md#v1140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/connectcases`: [v1.7.0](service/connectcases/CHANGELOG.md#v170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/connectcontactlens`: [v1.15.0](service/connectcontactlens/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/controltower`: [v1.3.0](service/controltower/CHANGELOG.md#v130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/databrew`: [v1.23.0](service/databrew/CHANGELOG.md#v1230-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/dataexchange`: [v1.21.0](service/dataexchange/CHANGELOG.md#v1210-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/datapipeline`: [v1.16.0](service/datapipeline/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/dax`: [v1.14.0](service/dax/CHANGELOG.md#v1140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/devicefarm`: [v1.17.0](service/devicefarm/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/docdbelastic`: [v1.3.0](service/docdbelastic/CHANGELOG.md#v130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/ec2instanceconnect`: [v1.17.0](service/ec2instanceconnect/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/ecrpublic`: [v1.18.0](service/ecrpublic/CHANGELOG.md#v1180-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk`: [v1.17.0](service/elasticbeanstalk/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing`: [v1.17.0](service/elasticloadbalancing/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/elastictranscoder`: [v1.16.0](service/elastictranscoder/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/evidently`: [v1.13.0](service/evidently/CHANGELOG.md#v1130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/finspacedata`: [v1.16.0](service/finspacedata/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/fis`: [v1.16.0](service/fis/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/forecast`: [v1.27.0](service/forecast/CHANGELOG.md#v1270-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/forecastquery`: [v1.15.0](service/forecastquery/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/gamesparks`: [v1.4.0](service/gamesparks/CHANGELOG.md#v140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/glacier`: [v1.16.0](service/glacier/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/greengrass`: [v1.17.0](service/greengrass/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/greengrassv2`: [v1.24.0](service/greengrassv2/CHANGELOG.md#v1240-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/honeycode`: [v1.15.0](service/honeycode/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/inspector`: [v1.15.0](service/inspector/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/iot1clickdevicesservice`: [v1.13.0](service/iot1clickdevicesservice/CHANGELOG.md#v1130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/iot1clickprojects`: [v1.14.0](service/iot1clickprojects/CHANGELOG.md#v1140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/iotanalytics`: [v1.16.0](service/iotanalytics/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/iotevents`: [v1.17.0](service/iotevents/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/ioteventsdata`: [v1.15.0](service/ioteventsdata/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/iotfleethub`: [v1.15.0](service/iotfleethub/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/iotjobsdataplane`: [v1.14.0](service/iotjobsdataplane/CHANGELOG.md#v1140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/iotroborunner`: [v1.3.0](service/iotroborunner/CHANGELOG.md#v130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/iotsecuretunneling`: [v1.17.0](service/iotsecuretunneling/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/iotthingsgraph`: [v1.16.0](service/iotthingsgraph/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/ivschat`: [v1.6.0](service/ivschat/CHANGELOG.md#v160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/kendraranking`: [v1.2.0](service/kendraranking/CHANGELOG.md#v120-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/kinesis`: [v1.19.0](service/kinesis/CHANGELOG.md#v1190-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/kinesisanalytics`: [v1.16.0](service/kinesisanalytics/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/kinesisvideoarchivedmedia`: [v1.17.0](service/kinesisvideoarchivedmedia/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/kinesisvideomedia`: [v1.13.0](service/kinesisvideomedia/CHANGELOG.md#v1130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/kinesisvideosignaling`: [v1.13.0](service/kinesisvideosignaling/CHANGELOG.md#v1130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/kinesisvideowebrtcstorage`: [v1.4.0](service/kinesisvideowebrtcstorage/CHANGELOG.md#v140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/lexmodelbuildingservice`: [v1.19.0](service/lexmodelbuildingservice/CHANGELOG.md#v1190-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/lexruntimeservice`: [v1.15.0](service/lexruntimeservice/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/lexruntimev2`: [v1.19.0](service/lexruntimev2/CHANGELOG.md#v1190-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/licensemanager`: [v1.20.0](service/licensemanager/CHANGELOG.md#v1200-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/licensemanagerlinuxsubscriptions`: [v1.3.0](service/licensemanagerlinuxsubscriptions/CHANGELOG.md#v130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/licensemanagerusersubscriptions`: [v1.4.0](service/licensemanagerusersubscriptions/CHANGELOG.md#v140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/lookoutmetrics`: [v1.21.0](service/lookoutmetrics/CHANGELOG.md#v1210-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/lookoutvision`: [v1.17.0](service/lookoutvision/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/machinelearning`: [v1.17.0](service/machinelearning/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/macie`: [v1.17.0](service/macie/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/macie2`: [v1.29.7](service/macie2/CHANGELOG.md#v1297-2023-09-18) + * **Documentation**: This release changes the default managedDataIdentifierSelector setting for new classification jobs to RECOMMENDED. By default, new classification jobs now use the recommended set of managed data identifiers. +* `github.com/aws/aws-sdk-go-v2/service/marketplacecommerceanalytics`: [v1.14.0](service/marketplacecommerceanalytics/CHANGELOG.md#v1140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/marketplaceentitlementservice`: [v1.14.0](service/marketplaceentitlementservice/CHANGELOG.md#v1140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/marketplacemetering`: [v1.16.0](service/marketplacemetering/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/mediapackagev2`: [v1.2.0](service/mediapackagev2/CHANGELOG.md#v120-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/mediapackagevod`: [v1.24.0](service/mediapackagevod/CHANGELOG.md#v1240-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/mediastore`: [v1.15.0](service/mediastore/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/mediastoredata`: [v1.15.0](service/mediastoredata/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/medicalimaging`: [v1.2.0](service/medicalimaging/CHANGELOG.md#v120-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/migrationhub`: [v1.15.0](service/migrationhub/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/migrationhubconfig`: [v1.15.0](service/migrationhubconfig/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/migrationhuborchestrator`: [v1.3.0](service/migrationhuborchestrator/CHANGELOG.md#v130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/migrationhubstrategy`: [v1.11.0](service/migrationhubstrategy/CHANGELOG.md#v1110-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/mobile`: [v1.14.0](service/mobile/CHANGELOG.md#v1140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/mturk`: [v1.16.0](service/mturk/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/neptune`: [v1.22.0](service/neptune/CHANGELOG.md#v1220-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/networkmanager`: [v1.19.0](service/networkmanager/CHANGELOG.md#v1190-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/nimble`: [v1.18.0](service/nimble/CHANGELOG.md#v1180-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/oam`: [v1.3.0](service/oam/CHANGELOG.md#v130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/opensearchserverless`: [v1.5.0](service/opensearchserverless/CHANGELOG.md#v150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/opsworks`: [v1.16.0](service/opsworks/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/opsworkscm`: [v1.17.0](service/opsworkscm/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/osis`: [v1.2.0](service/osis/CHANGELOG.md#v120-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/panorama`: [v1.13.0](service/panorama/CHANGELOG.md#v1130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/paymentcryptography`: [v1.2.0](service/paymentcryptography/CHANGELOG.md#v120-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/personalizeevents`: [v1.15.0](service/personalizeevents/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/personalizeruntime`: [v1.15.0](service/personalizeruntime/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/pinpointemail`: [v1.14.0](service/pinpointemail/CHANGELOG.md#v1140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/pinpointsmsvoice`: [v1.13.0](service/pinpointsmsvoice/CHANGELOG.md#v1130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/pinpointsmsvoicev2`: [v1.3.0](service/pinpointsmsvoicev2/CHANGELOG.md#v130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/pipes`: [v1.4.0](service/pipes/CHANGELOG.md#v140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/qldbsession`: [v1.16.0](service/qldbsession/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/rbin`: [v1.10.0](service/rbin/CHANGELOG.md#v1100-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/rdsdata`: [v1.15.0](service/rdsdata/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/redshiftserverless`: [v1.6.0](service/redshiftserverless/CHANGELOG.md#v160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/resourceexplorer2`: [v1.4.0](service/resourceexplorer2/CHANGELOG.md#v140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/resourcegroups`: [v1.16.0](service/resourcegroups/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi`: [v1.16.0](service/resourcegroupstaggingapi/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/robomaker`: [v1.20.0](service/robomaker/CHANGELOG.md#v1200-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/route53recoverycluster`: [v1.13.0](service/route53recoverycluster/CHANGELOG.md#v1130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/route53recoverycontrolconfig`: [v1.13.0](service/route53recoverycontrolconfig/CHANGELOG.md#v1130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/route53recoveryreadiness`: [v1.11.0](service/route53recoveryreadiness/CHANGELOG.md#v1110-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/route53resolver`: [v1.20.0](service/route53resolver/CHANGELOG.md#v1200-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/rum`: [v1.12.0](service/rum/CHANGELOG.md#v1120-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/s3outposts`: [v1.18.0](service/s3outposts/CHANGELOG.md#v1180-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/sagemakera2iruntime`: [v1.17.0](service/sagemakera2iruntime/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/sagemakeredge`: [v1.15.0](service/sagemakeredge/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/sagemakergeospatial`: [v1.5.0](service/sagemakergeospatial/CHANGELOG.md#v150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/sagemakermetrics`: [v1.2.0](service/sagemakermetrics/CHANGELOG.md#v120-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/scheduler`: [v1.3.0](service/scheduler/CHANGELOG.md#v130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/schemas`: [v1.17.0](service/schemas/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/serverlessapplicationrepository`: [v1.14.0](service/serverlessapplicationrepository/CHANGELOG.md#v1140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/servicecatalogappregistry`: [v1.19.0](service/servicecatalogappregistry/CHANGELOG.md#v1190-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/servicediscovery`: [v1.23.0](service/servicediscovery/CHANGELOG.md#v1230-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/shield`: [v1.20.0](service/shield/CHANGELOG.md#v1200-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/sms`: [v1.15.0](service/sms/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/snowdevicemanagement`: [v1.11.0](service/snowdevicemanagement/CHANGELOG.md#v1110-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/sns`: [v1.22.0](service/sns/CHANGELOG.md#v1220-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/ssmcontacts`: [v1.17.0](service/ssmcontacts/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/ssmincidents`: [v1.23.0](service/ssmincidents/CHANGELOG.md#v1230-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/ssmsap`: [v1.5.0](service/ssmsap/CHANGELOG.md#v150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/sso`: [v1.14.0](service/sso/CHANGELOG.md#v1140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/ssooidc`: [v1.16.0](service/ssooidc/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/storagegateway`: [v1.20.0](service/storagegateway/CHANGELOG.md#v1200-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/sts`: [v1.22.0](service/sts/CHANGELOG.md#v1220-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/supportapp`: [v1.4.0](service/supportapp/CHANGELOG.md#v140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/synthetics`: [v1.19.0](service/synthetics/CHANGELOG.md#v1190-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/textract`: [v1.23.0](service/textract/CHANGELOG.md#v1230-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/timestreamquery`: [v1.17.0](service/timestreamquery/CHANGELOG.md#v1170-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/timestreamwrite`: [v1.19.0](service/timestreamwrite/CHANGELOG.md#v1190-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/tnb`: [v1.3.0](service/tnb/CHANGELOG.md#v130-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/transcribestreaming`: [v1.11.0](service/transcribestreaming/CHANGELOG.md#v1110-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/voiceid`: [v1.15.0](service/voiceid/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/waf`: [v1.14.0](service/waf/CHANGELOG.md#v1140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/wafregional`: [v1.15.0](service/wafregional/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/workdocs`: [v1.16.0](service/workdocs/CHANGELOG.md#v1160-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/worklink`: [v1.15.0](service/worklink/CHANGELOG.md#v1150-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* `github.com/aws/aws-sdk-go-v2/service/workmail`: [v1.20.0](service/workmail/CHANGELOG.md#v1200-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. + * **Feature**: This release includes four new APIs UpdateUser, UpdateGroup, ListGroupsForEntity and DescribeEntity, along with RemoteUsers and some enhancements to existing APIs. +* `github.com/aws/aws-sdk-go-v2/service/workmailmessageflow`: [v1.14.0](service/workmailmessageflow/CHANGELOG.md#v1140-2023-09-18) + * **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. + +# Release (2023-09-15) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/appstream`: [v1.24.0](service/appstream/CHANGELOG.md#v1240-2023-09-15) + * **Feature**: This release introduces app block builder, allowing customers to provision a resource to package applications into an app block +* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.67.0](service/connect/CHANGELOG.md#v1670-2023-09-15) + * **Feature**: New rule type (OnMetricDataUpdate) has been added +* `github.com/aws/aws-sdk-go-v2/service/datasync`: [v1.29.1](service/datasync/CHANGELOG.md#v1291-2023-09-15) + * **Documentation**: Documentation-only updates for AWS DataSync. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.106.0](service/sagemaker/CHANGELOG.md#v11060-2023-09-15) + * **Feature**: This release introduces Skip Model Validation for Model Packages + +# Release (2023-09-14) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/appstream`: [v1.23.0](service/appstream/CHANGELOG.md#v1230-2023-09-14) + * **Feature**: This release introduces multi-session fleets, allowing customers to provision more than one user session on a single fleet instance. +* `github.com/aws/aws-sdk-go-v2/service/cloudformation`: [v1.34.6](service/cloudformation/CHANGELOG.md#v1346-2023-09-14) + * **Documentation**: Documentation updates for AWS CloudFormation +* `github.com/aws/aws-sdk-go-v2/service/entityresolution`: [v1.2.0](service/entityresolution/CHANGELOG.md#v120-2023-09-14) + * **Feature**: Changed "ResolutionTechniques" and "MappedInputFields" in workflow and schema mapping operations to be required fields. +* `github.com/aws/aws-sdk-go-v2/service/lookoutequipment`: [v1.19.0](service/lookoutequipment/CHANGELOG.md#v1190-2023-09-14) + * **Feature**: This release adds APIs for the new scheduled retraining feature. + +# Release (2023-09-13) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/cloud9`: [v1.18.8](service/cloud9/CHANGELOG.md#v1188-2023-09-13) + * **Documentation**: Update to include information on Ubuntu 18 deprecation. +* `github.com/aws/aws-sdk-go-v2/service/drs`: [v1.16.0](service/drs/CHANGELOG.md#v1160-2023-09-13) + * **Feature**: Updated existing APIs and added new ones to support using AWS Elastic Disaster Recovery post-launch actions. Added support for new regions. +* `github.com/aws/aws-sdk-go-v2/service/firehose`: [v1.18.0](service/firehose/CHANGELOG.md#v1180-2023-09-13) + * **Feature**: DocumentIdOptions has been added for the Amazon OpenSearch destination. +* `github.com/aws/aws-sdk-go-v2/service/guardduty`: [v1.27.0](service/guardduty/CHANGELOG.md#v1270-2023-09-13) + * **Feature**: Add `managementType` field to ListCoverage API response. +* `github.com/aws/aws-sdk-go-v2/service/internetmonitor`: [v1.6.0](service/internetmonitor/CHANGELOG.md#v160-2023-09-13) + * **Feature**: This release updates the Amazon CloudWatch Internet Monitor API domain name. +* `github.com/aws/aws-sdk-go-v2/service/ivsrealtime`: [v1.4.4](service/ivsrealtime/CHANGELOG.md#v144-2023-09-13) + * **Documentation**: Doc only update that changes description for ParticipantToken. +* `github.com/aws/aws-sdk-go-v2/service/simspaceweaver`: [v1.5.1](service/simspaceweaver/CHANGELOG.md#v151-2023-09-13) + * **Documentation**: Edited the introductory text for the API reference. +* `github.com/aws/aws-sdk-go-v2/service/xray`: [v1.18.0](service/xray/CHANGELOG.md#v1180-2023-09-13) + * **Feature**: Add StartTime field in GetTraceSummaries API response for each TraceSummary. + +# Release (2023-09-12) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.118.0](service/ec2/CHANGELOG.md#v11180-2023-09-12) + * **Feature**: This release adds support for restricting public sharing of AMIs through AMI Block Public Access +* `github.com/aws/aws-sdk-go-v2/service/eventbridge`: [v1.22.0](service/eventbridge/CHANGELOG.md#v1220-2023-09-12) + * **Feature**: Adds sensitive trait to various shapes in Jetstream Connections API model. +* `github.com/aws/aws-sdk-go-v2/service/kendra`: [v1.43.0](service/kendra/CHANGELOG.md#v1430-2023-09-12) + * **Feature**: Amazon Kendra now supports confidence score buckets for retrieved passage results using the Retrieve API. + +# Release (2023-09-11) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/ecr`: [v1.20.0](service/ecr/CHANGELOG.md#v1200-2023-09-11) + * **Feature**: This release will have ValidationException be thrown from ECR LifecyclePolicy APIs in regions LifecyclePolicy is not supported, this includes existing Amazon Dedicated Cloud (ADC) regions. This release will also change Tag: TagValue and Tag: TagKey to required. +* `github.com/aws/aws-sdk-go-v2/service/medialive`: [v1.37.0](service/medialive/CHANGELOG.md#v1370-2023-09-11) + * **Feature**: AWS Elemental Link now supports attaching a Link UHD device to a MediaConnect flow. +* `github.com/aws/aws-sdk-go-v2/service/quicksight`: [v1.43.0](service/quicksight/CHANGELOG.md#v1430-2023-09-11) + * **Feature**: This release launches new updates to QuickSight KPI visuals - support for sparklines, new templated layout and new targets for conditional formatting rules. + +# Release (2023-09-08) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/fsx`: [v1.32.6](service/fsx/CHANGELOG.md#v1326-2023-09-08) + * **Documentation**: Amazon FSx documentation fixes +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.105.0](service/sagemaker/CHANGELOG.md#v11050-2023-09-08) + * **Feature**: Autopilot APIs will now support holiday featurization for Timeseries models. The models will now hold holiday metadata and should be able to accommodate holiday effect during inference. +* `github.com/aws/aws-sdk-go-v2/service/ssoadmin`: [v1.18.0](service/ssoadmin/CHANGELOG.md#v1180-2023-09-08) + * **Feature**: Content updates to IAM Identity Center API for China Regions. +* `github.com/aws/aws-sdk-go-v2/service/workspaces`: [v1.30.0](service/workspaces/CHANGELOG.md#v1300-2023-09-08) + * **Feature**: A new field "ErrorDetails" will be added to the output of "DescribeWorkspaceImages" API call. This field provides in-depth details about the error occurred during image import process. These details include the possible causes of the errors and troubleshooting information. + +# Release (2023-09-07) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/securityhub`: [v1.36.2](service/securityhub/CHANGELOG.md#v1362-2023-09-07) + * **Documentation**: Documentation updates for AWS Security Hub +* `github.com/aws/aws-sdk-go-v2/service/simspaceweaver`: [v1.5.0](service/simspaceweaver/CHANGELOG.md#v150-2023-09-07) + * **Feature**: BucketName and ObjectKey are now required for the S3Location data type. BucketName is now required for the S3Destination data type. + +# Release (2023-09-06) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/appflow`: [v1.35.0](service/appflow/CHANGELOG.md#v1350-2023-09-06) + * **Feature**: Adding OAuth2.0 support for servicenow connector. +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.117.0](service/ec2/CHANGELOG.md#v11170-2023-09-06) + * **Feature**: This release adds 'outpost' location type to the DescribeInstanceTypeOfferings API, allowing customers that have been allowlisted for outpost to query their offerings in the API. +* `github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2`: [v1.21.4](service/elasticloadbalancingv2/CHANGELOG.md#v1214-2023-09-06) + * **Documentation**: This release enables default UDP connection termination and disabling unhealthy target connection termination for Network Load Balancers. +* `github.com/aws/aws-sdk-go-v2/service/medialive`: [v1.36.0](service/medialive/CHANGELOG.md#v1360-2023-09-06) + * **Feature**: Adds advanced Output Locking options for Epoch Locking: Custom Epoch and Jam Sync Time +* `github.com/aws/aws-sdk-go-v2/service/wafv2`: [v1.38.0](service/wafv2/CHANGELOG.md#v1380-2023-09-06) + * **Feature**: The targeted protection level of the Bot Control managed rule group now provides optional, machine-learning analysis of traffic statistics to detect some bot-related activity. You can enable or disable the machine learning functionality through the API. + +# Release (2023-09-05) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/billingconductor`: [v1.9.0](service/billingconductor/CHANGELOG.md#v190-2023-09-05) + * **Feature**: This release adds support for line item filtering in for the custom line item resource. +* `github.com/aws/aws-sdk-go-v2/service/cloud9`: [v1.18.7](service/cloud9/CHANGELOG.md#v1187-2023-09-05) + * **Documentation**: Added support for Ubuntu 22.04 that was not picked up in a previous Trebuchet request. Doc-only update. +* `github.com/aws/aws-sdk-go-v2/service/computeoptimizer`: [v1.27.0](service/computeoptimizer/CHANGELOG.md#v1270-2023-09-05) + * **Feature**: This release adds support to provide recommendations for G4dn and P3 instances that use NVIDIA GPUs. +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.116.0](service/ec2/CHANGELOG.md#v11160-2023-09-05) + * **Feature**: Introducing Amazon EC2 C7gd, M7gd, and R7gd Instances with up to 3.8 TB of local NVMe-based SSD block-level storage. These instances are powered by AWS Graviton3 processors, delivering up to 25% better performance over Graviton2-based instances. +* `github.com/aws/aws-sdk-go-v2/service/ecs`: [v1.30.1](service/ecs/CHANGELOG.md#v1301-2023-09-05) + * **Documentation**: Documentation only update for Amazon ECS. +* `github.com/aws/aws-sdk-go-v2/service/eventbridge`: [v1.21.0](service/eventbridge/CHANGELOG.md#v1210-2023-09-05) + * **Feature**: Improve Endpoint Ruleset test coverage. +* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.54.0](service/rds/CHANGELOG.md#v1540-2023-09-05) + * **Feature**: Add support for feature integration with AWS Backup. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.104.0](service/sagemaker/CHANGELOG.md#v11040-2023-09-05) + * **Feature**: SageMaker Neo now supports data input shape derivation for Pytorch 2.0 and XGBoost compilation job for cloud instance targets. You can skip DataInputConfig field during compilation job creation. You can also access derived information from model in DescribeCompilationJob response. +* `github.com/aws/aws-sdk-go-v2/service/vpclattice`: [v1.2.0](service/vpclattice/CHANGELOG.md#v120-2023-09-05) + * **Feature**: This release adds Lambda event structure version config support for LAMBDA target groups. It also adds newline support for auth policies. + +# Release (2023-09-01) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/chimesdkmediapipelines`: [v1.8.0](service/chimesdkmediapipelines/CHANGELOG.md#v180-2023-09-01) + * **Feature**: This release adds support for the Voice Analytics feature for customer-owned KVS streams as part of the Amazon Chime SDK call analytics. +* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.66.0](service/connect/CHANGELOG.md#v1660-2023-09-01) + * **Feature**: Amazon Connect adds the ability to read, create, update, delete, and list view resources, and adds the ability to read, create, delete, and list view versions. +* `github.com/aws/aws-sdk-go-v2/service/identitystore`: [v1.18.0](service/identitystore/CHANGELOG.md#v1180-2023-09-01) + * **Feature**: New Identity Store content for China Region launch +* `github.com/aws/aws-sdk-go-v2/service/neptunedata`: [v1.0.1](service/neptunedata/CHANGELOG.md#v101-2023-09-01) + * **Documentation**: Removed the descriptive text in the introduction. + +# Release (2023-08-31) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/chimesdkmediapipelines`: [v1.7.0](service/chimesdkmediapipelines/CHANGELOG.md#v170-2023-08-31) + * **Feature**: This release adds support for feature Voice Enhancement for Call Recording as part of Amazon Chime SDK call analytics. +* `github.com/aws/aws-sdk-go-v2/service/cloudhsm`: [v1.15.0](service/cloudhsm/CHANGELOG.md#v1150-2023-08-31) + * **Feature**: Deprecating CloudHSM Classic API Service. +* `github.com/aws/aws-sdk-go-v2/service/cloudwatchevents`: [v1.17.0](service/cloudwatchevents/CHANGELOG.md#v1170-2023-08-31) + * **Feature**: Documentation updates for CloudWatch Events. +* `github.com/aws/aws-sdk-go-v2/service/connectcampaigns`: [v1.4.0](service/connectcampaigns/CHANGELOG.md#v140-2023-08-31) + * **Feature**: Amazon Connect outbound campaigns has launched agentless dialing mode which enables customers to make automated outbound calls without agent engagement. This release updates three of the campaign management API's to support the new agentless dialing mode and the new dialing capacity field. +* `github.com/aws/aws-sdk-go-v2/service/connectparticipant`: [v1.17.0](service/connectparticipant/CHANGELOG.md#v1170-2023-08-31) + * **Feature**: Amazon Connect Participant Service adds the ability to get a view resource using a view token, which is provided in a participant message, with the release of the DescribeView API. +* `github.com/aws/aws-sdk-go-v2/service/customerprofiles`: [v1.28.0](service/customerprofiles/CHANGELOG.md#v1280-2023-08-31) + * **Feature**: Adds sensitive trait to various shapes in Customer Profiles API model. +* `github.com/aws/aws-sdk-go-v2/service/ecs`: [v1.30.0](service/ecs/CHANGELOG.md#v1300-2023-08-31) + * **Feature**: This release adds support for an account-level setting that you can use to configure the number of days for AWS Fargate task retirement. +* `github.com/aws/aws-sdk-go-v2/service/health`: [v1.19.0](service/health/CHANGELOG.md#v1190-2023-08-31) + * **Feature**: Adds new API DescribeEntityAggregatesForOrganization that retrieves entity aggregates across your organization. Also adds support for resource status filtering in DescribeAffectedEntitiesForOrganization, resource status aggregates in the DescribeEntityAggregates response, and new resource statuses. +* `github.com/aws/aws-sdk-go-v2/service/ivs`: [v1.26.0](service/ivs/CHANGELOG.md#v1260-2023-08-31) + * **Feature**: Updated "type" description for CreateChannel, UpdateChannel, Channel, and ChannelSummary. +* `github.com/aws/aws-sdk-go-v2/service/kafkaconnect`: [v1.11.0](service/kafkaconnect/CHANGELOG.md#v1110-2023-08-31) + * **Feature**: Minor model changes for Kafka Connect as well as endpoint updates. +* `github.com/aws/aws-sdk-go-v2/service/paymentcryptographydata`: [v1.2.0](service/paymentcryptographydata/CHANGELOG.md#v120-2023-08-31) + * **Feature**: Make KeyCheckValue field optional when using asymmetric keys as Key Check Values typically only apply to symmetric keys +* `github.com/aws/aws-sdk-go-v2/service/sagemakerruntime`: [v1.21.0](service/sagemakerruntime/CHANGELOG.md#v1210-2023-08-31) + * **Feature**: This release adds a new InvokeEndpointWithResponseStream API to support streaming of model responses. + +# Release (2023-08-30) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/appflow`: [v1.34.0](service/appflow/CHANGELOG.md#v1340-2023-08-30) + * **Feature**: Add SAP source connector parallel and pagination feature +* `github.com/aws/aws-sdk-go-v2/service/apprunner`: [v1.19.0](service/apprunner/CHANGELOG.md#v1190-2023-08-30) + * **Feature**: App Runner adds support for Bitbucket. You can now create App Runner connection that connects to your Bitbucket repositories and deploy App Runner service with the source code stored in a Bitbucket repository. +* `github.com/aws/aws-sdk-go-v2/service/cleanrooms`: [v1.4.0](service/cleanrooms/CHANGELOG.md#v140-2023-08-30) + * **Feature**: This release decouples member abilities in a collaboration. With this change, the member who can run queries no longer needs to be the same as the member who can receive results. +* `github.com/aws/aws-sdk-go-v2/service/datasync`: [v1.29.0](service/datasync/CHANGELOG.md#v1290-2023-08-30) + * **Feature**: AWS DataSync introduces Task Reports, a new feature that provides detailed reports of data transfer operations for each task execution. +* `github.com/aws/aws-sdk-go-v2/service/neptunedata`: [v1.0.0](service/neptunedata/CHANGELOG.md#v100-2023-08-30) + * **Release**: New AWS service client module + * **Feature**: Allows customers to execute data plane actions like bulk loading graphs, issuing graph queries using Gremlin and openCypher directly from the SDK. +* `github.com/aws/aws-sdk-go-v2/service/networkfirewall`: [v1.30.0](service/networkfirewall/CHANGELOG.md#v1300-2023-08-30) + * **Feature**: Network Firewall increasing pagination token string length +* `github.com/aws/aws-sdk-go-v2/service/pcaconnectorad`: [v1.0.0](service/pcaconnectorad/CHANGELOG.md#v100-2023-08-30) + * **Release**: New AWS service client module + * **Feature**: The Connector for AD allows you to use a fully-managed AWS Private CA as a drop-in replacement for your self-managed enterprise CAs without local agents or proxy servers. Enterprises that use AD to manage Windows environments can reduce their private certificate authority (CA) costs and complexity. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.103.0](service/sagemaker/CHANGELOG.md#v11030-2023-08-30) + * **Feature**: Amazon SageMaker Canvas adds IdentityProviderOAuthSettings support for CanvasAppSettings + +# Release (2023-08-29) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider`: [v1.26.0](service/cognitoidentityprovider/CHANGELOG.md#v1260-2023-08-29) + * **Feature**: Added API example requests and responses for several operations. Fixed the validation regex for user pools Identity Provider name. +* `github.com/aws/aws-sdk-go-v2/service/fsx`: [v1.32.5](service/fsx/CHANGELOG.md#v1325-2023-08-29) + * **Documentation**: Documentation updates for project quotas. +* `github.com/aws/aws-sdk-go-v2/service/omics`: [v1.9.0](service/omics/CHANGELOG.md#v190-2023-08-29) + * **Feature**: Add RetentionMode support for Runs. +* `github.com/aws/aws-sdk-go-v2/service/sesv2`: [v1.20.0](service/sesv2/CHANGELOG.md#v1200-2023-08-29) + * **Feature**: Adds support for the new Export and Message Insights features: create, get, list and cancel export jobs; get message insights. + +# Release (2023-08-28) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/backup`: [v1.25.0](service/backup/CHANGELOG.md#v1250-2023-08-28) + * **Feature**: Add support for customizing time zone for backup window in backup plan rules. +* `github.com/aws/aws-sdk-go-v2/service/computeoptimizer`: [v1.26.0](service/computeoptimizer/CHANGELOG.md#v1260-2023-08-28) + * **Feature**: This release enables AWS Compute Optimizer to analyze and generate licensing optimization recommendations for sql server running on EC2 instances. +* `github.com/aws/aws-sdk-go-v2/service/organizations`: [v1.20.6](service/organizations/CHANGELOG.md#v1206-2023-08-28) + * **Documentation**: Documentation updates for permissions and links. +* `github.com/aws/aws-sdk-go-v2/service/securitylake`: [v1.7.0](service/securitylake/CHANGELOG.md#v170-2023-08-28) + * **Feature**: Remove incorrect regex enforcement on pagination tokens. +* `github.com/aws/aws-sdk-go-v2/service/servicequotas`: [v1.16.0](service/servicequotas/CHANGELOG.md#v1160-2023-08-28) + * **Feature**: Service Quotas now supports viewing the applied quota value and requesting a quota increase for a specific resource in an AWS account. +* `github.com/aws/aws-sdk-go-v2/service/workspacesweb`: [v1.12.0](service/workspacesweb/CHANGELOG.md#v1120-2023-08-28) + * **Feature**: WorkSpaces Web now enables Admins to configure which cookies are synchronized from an end-user's local browser to the in-session browser. In conjunction with a browser extension, this feature enables enhanced Single-Sign On capability by reducing the number of times an end-user has to authenticate. + +# Release (2023-08-25) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/cloudtrail`: [v1.29.0](service/cloudtrail/CHANGELOG.md#v1290-2023-08-25) + * **Feature**: Add ThrottlingException with error code 429 to handle CloudTrail Delegated Admin request rate exceeded on organization resources. +* `github.com/aws/aws-sdk-go-v2/service/cloudwatch`: [v1.27.7](service/cloudwatch/CHANGELOG.md#v1277-2023-08-25) + * **Documentation**: Doc-only update to get doc bug fixes into the SDK docs + +# Release (2023-08-24) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.115.0](service/ec2/CHANGELOG.md#v11150-2023-08-24) + * **Feature**: Amazon EC2 M7a instances, powered by 4th generation AMD EPYC processors, deliver up to 50% higher performance compared to M6a instances. Amazon EC2 Hpc7a instances, powered by 4th Gen AMD EPYC processors, deliver up to 2.5x better performance compared to Amazon EC2 Hpc6a instances. +* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.62.0](service/glue/CHANGELOG.md#v1620-2023-08-24) + * **Feature**: Added API attributes that help in the monitoring of sessions. +* `github.com/aws/aws-sdk-go-v2/service/mediaconvert`: [v1.41.0](service/mediaconvert/CHANGELOG.md#v1410-2023-08-24) + * **Feature**: This release includes additional audio channel tags in Quicktime outputs, support for film grain synthesis for AV1 outputs, ability to create audio-only FLAC outputs, and ability to specify Amazon S3 destination storage class. +* `github.com/aws/aws-sdk-go-v2/service/medialive`: [v1.35.0](service/medialive/CHANGELOG.md#v1350-2023-08-24) + * **Feature**: MediaLive now supports passthrough of KLV data to a HLS output group with a TS container. MediaLive now supports setting an attenuation mode for AC3 audio when the coding mode is 3/2 LFE. MediaLive now supports specifying whether to include filler NAL units in RTMP output group settings. +* `github.com/aws/aws-sdk-go-v2/service/mediatailor`: [v1.27.0](service/mediatailor/CHANGELOG.md#v1270-2023-08-24) + * **Feature**: Adds new source location AUTODETECT_SIGV4 access type. +* `github.com/aws/aws-sdk-go-v2/service/quicksight`: [v1.42.0](service/quicksight/CHANGELOG.md#v1420-2023-08-24) + * **Feature**: Excel support in Snapshot Export APIs. Removed Required trait for some insight Computations. Namespace-shared Folders support. Global Filters support. Table pin Column support. +* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.53.0](service/rds/CHANGELOG.md#v1530-2023-08-24) + * **Feature**: This release updates the supported versions for Percona XtraBackup in Aurora MySQL. +* `github.com/aws/aws-sdk-go-v2/service/s3control`: [v1.33.0](service/s3control/CHANGELOG.md#v1330-2023-08-24) + * **Feature**: Updates to endpoint ruleset tests to address Smithy validation issues and standardize the capitalization of DualStack. +* `github.com/aws/aws-sdk-go-v2/service/verifiedpermissions`: [v1.2.1](service/verifiedpermissions/CHANGELOG.md#v121-2023-08-24) + * **Documentation**: Documentation updates for Amazon Verified Permissions. + +# Release (2023-08-23) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/apigateway`: [v1.18.0](service/apigateway/CHANGELOG.md#v1180-2023-08-23) + * **Feature**: This release adds RootResourceId to GetRestApi response. +* `github.com/aws/aws-sdk-go-v2/service/polly`: [v1.31.0](service/polly/CHANGELOG.md#v1310-2023-08-23) + * **Feature**: Amazon Polly adds 1 new voice - Zayd (ar-AE) + +# Release (2023-08-22) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/costexplorer`: [v1.28.0](service/costexplorer/CHANGELOG.md#v1280-2023-08-22) + * **Feature**: This release adds the LastUpdatedDate and LastUsedDate timestamps to help you manage your cost allocation tags. +* `github.com/aws/aws-sdk-go-v2/service/globalaccelerator`: [v1.17.7](service/globalaccelerator/CHANGELOG.md#v1177-2023-08-22) + * **Documentation**: Global Accelerator now supports Client Ip Preservation for Network Load Balancer endpoints. +* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.52.0](service/rds/CHANGELOG.md#v1520-2023-08-22) + * **Feature**: Adding parameters to CreateCustomDbEngineVersion reserved for future use. +* `github.com/aws/aws-sdk-go-v2/service/verifiedpermissions`: [v1.2.0](service/verifiedpermissions/CHANGELOG.md#v120-2023-08-22) + * **Feature**: Documentation updates for Amazon Verified Permissions. Increases max results per page for ListPolicyStores, ListPolicies, and ListPolicyTemplates APIs from 20 to 50. + +# Release (2023-08-21) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2`: v1.21.0 + * **Feature**: Add support for polly SynthesizeSpeech GET request presigner +* `github.com/aws/aws-sdk-go-v2/service/cloud9`: [v1.18.6](service/cloud9/CHANGELOG.md#v1186-2023-08-21) + * **Documentation**: Doc only update to add Ubuntu 22.04 as an Image ID option for Cloud9 +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.114.0](service/ec2/CHANGELOG.md#v11140-2023-08-21) + * **Feature**: The DeleteKeyPair API has been updated to return the keyPairId when an existing key pair is deleted. +* `github.com/aws/aws-sdk-go-v2/service/finspace`: [v1.12.0](service/finspace/CHANGELOG.md#v1120-2023-08-21) + * **Feature**: Allow customers to manage outbound traffic from their Kx Environment when attaching a transit gateway by providing network acl entries. Allow the customer to choose how they want to update the databases on a cluster allowing updates to possibly be faster than usual. +* `github.com/aws/aws-sdk-go-v2/service/polly`: [v1.30.0](service/polly/CHANGELOG.md#v1300-2023-08-21) + * **Feature**: Add support for polly SynthesizeSpeech GET request presigner +* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.51.0](service/rds/CHANGELOG.md#v1510-2023-08-21) + * **Feature**: Adding support for RDS Aurora Global Database Unplanned Failover +* `github.com/aws/aws-sdk-go-v2/service/route53domains`: [v1.17.3](service/route53domains/CHANGELOG.md#v1173-2023-08-21) + * **Documentation**: Fixed typos in description fields + +# Release (2023-08-18) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/codecommit`: [v1.16.0](service/codecommit/CHANGELOG.md#v1160-2023-08-18) + * **Feature**: Add new ListFileCommitHistory operation to retrieve commits which introduced changes to a specific file. +* `github.com/aws/aws-sdk-go-v2/service/securityhub`: [v1.36.0](service/securityhub/CHANGELOG.md#v1360-2023-08-18) + * **Feature**: Added Inspector Lambda code Vulnerability section to ASFF, including GeneratorDetails, EpssScore, ExploitAvailable, and CodeVulnerabilities. + +# Release (2023-08-17) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2`: v1.20.2 + * **Bug Fix**: Sign `X-Amz-Server-Side-Encryption-Context` header to fix signing for PutObject requests that set `SSEKMSEncryptionContext`. +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.113.0](service/ec2/CHANGELOG.md#v11130-2023-08-17) + * **Feature**: Adds support for SubnetConfigurations to allow users to select their own IPv4 and IPv6 addresses for Interface VPC endpoints +* `github.com/aws/aws-sdk-go-v2/service/gamelift`: [v1.22.0](service/gamelift/CHANGELOG.md#v1220-2023-08-17) + * **Feature**: Amazon GameLift updates its instance types support. +* `github.com/aws/aws-sdk-go-v2/service/s3control`: [v1.32.3](service/s3control/CHANGELOG.md#v1323-2023-08-17) + * **Announcement**: BREAKFIX: corrected function spelling in environment config from GetS3DisableMultRegionAccessPoints to GetS3DisableMultiRegionAccessPoints + * **Bug Fix**: Adds DisableMRAP option to config loader, and DisableMRAP client resolver to achieve parity with other S3 options in the config loader. Additionally, added breakfix to correct spelling. + +# Release (2023-08-16) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/cloudwatch`: [v1.27.3](service/cloudwatch/CHANGELOG.md#v1273-2023-08-16) + * **Documentation**: Doc-only update to incorporate several doc bug fixes + +# Release (2023-08-15) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/chimesdkmeetings`: [v1.17.0](service/chimesdkmeetings/CHANGELOG.md#v1170-2023-08-15) + * **Feature**: Updated API documentation to include additional exceptions. +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.112.0](service/ec2/CHANGELOG.md#v11120-2023-08-15) + * **Feature**: Documentation updates for Elastic Compute Cloud (EC2). +* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.61.0](service/glue/CHANGELOG.md#v1610-2023-08-15) + * **Feature**: AWS Glue Crawlers can now accept SerDe overrides from a custom csv classifier. The two SerDe options are LazySimpleSerDe and OpenCSVSerDe. In case, the user wants crawler to do the selection, "None" can be selected for this purpose. +* `github.com/aws/aws-sdk-go-v2/service/pi`: [v1.19.0](service/pi/CHANGELOG.md#v1190-2023-08-15) + * **Feature**: AWS Performance Insights for Amazon RDS is launching Performance Analysis On Demand, a new feature that allows you to analyze database performance metrics and find out the performance issues. You can now use SDK to create, list, get, delete, and manage tags of performance analysis reports. +* `github.com/aws/aws-sdk-go-v2/service/route53domains`: [v1.17.0](service/route53domains/CHANGELOG.md#v1170-2023-08-15) + * **Feature**: Provide explanation if CheckDomainTransferability return false. Provide requestId if a request is already submitted. Add sensitive protection for customer information +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.102.0](service/sagemaker/CHANGELOG.md#v11020-2023-08-15) + * **Feature**: SageMaker Inference Recommender now provides SupportedResponseMIMETypes from DescribeInferenceRecommendationsJob response + +# Release (2023-08-14) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/mediapackage`: [v1.23.0](service/mediapackage/CHANGELOG.md#v1230-2023-08-14) + * **Feature**: Fix SDK logging of certain fields. +* `github.com/aws/aws-sdk-go-v2/service/omics`: [v1.8.0](service/omics/CHANGELOG.md#v180-2023-08-14) + * **Feature**: This release provides support for annotation store versioning and cross account sharing for Omics Analytics +* `github.com/aws/aws-sdk-go-v2/service/transfer`: [v1.33.4](service/transfer/CHANGELOG.md#v1334-2023-08-14) + * **Documentation**: Documentation updates for AWS Transfer Family + +# Release (2023-08-11) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/amplifybackend`: [v1.16.0](service/amplifybackend/CHANGELOG.md#v1160-2023-08-11) + * **Feature**: Adds sensitive trait to required input shapes. +* `github.com/aws/aws-sdk-go-v2/service/configservice`: [v1.36.0](service/configservice/CHANGELOG.md#v1360-2023-08-11) + * **Feature**: Updated ResourceType enum with new resource types onboarded by AWS Config in July 2023. +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.111.0](service/ec2/CHANGELOG.md#v11110-2023-08-11) + * **Feature**: Amazon EC2 P5 instances, powered by the latest NVIDIA H100 Tensor Core GPUs, deliver the highest performance in EC2 for deep learning (DL) and HPC applications. M7i-flex and M7i instances are next-generation general purpose instances powered by custom 4th Generation Intel Xeon Scalable processors. +* `github.com/aws/aws-sdk-go-v2/service/quicksight`: [v1.41.0](service/quicksight/CHANGELOG.md#v1410-2023-08-11) + * **Feature**: New Authentication method for Account subscription - IAM Identity Center. Hierarchy layout support, default column width support and related style properties for pivot table visuals. Non-additive topic field aggregations for Topic API +* `github.com/aws/aws-sdk-go-v2/service/ses`: [v1.16.3](service/ses/CHANGELOG.md#v1163-2023-08-11) + * **Documentation**: Doc only updates to include: 1) Clarified which part of an email address where it's okay to have Punycode when it contains non-ASCII characters for the SendRawEmail action and other actions where this is applicable. 2) Updated S3Action description with new MB max bucket size from 30 to 40. +* `github.com/aws/aws-sdk-go-v2/service/swf`: [v1.17.0](service/swf/CHANGELOG.md#v1170-2023-08-11) + * **Feature**: This release adds new API parameters to override workflow task list for workflow executions. + +# Release (2023-08-10) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/cloudtrail`: [v1.28.3](service/cloudtrail/CHANGELOG.md#v1283-2023-08-10) + * **Documentation**: Documentation updates for CloudTrail. +* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.65.0](service/connect/CHANGELOG.md#v1650-2023-08-10) + * **Feature**: This release adds APIs to provision agents that are global / available in multiple AWS regions and distribute them across these regions by percentage. +* `github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2`: [v1.21.0](service/elasticloadbalancingv2/CHANGELOG.md#v1210-2023-08-10) + * **Feature**: This release enables configuring security groups for Network Load Balancers +* `github.com/aws/aws-sdk-go-v2/service/omics`: [v1.7.0](service/omics/CHANGELOG.md#v170-2023-08-10) + * **Feature**: This release adds instanceType to GetRunTask & ListRunTasks responses. +* `github.com/aws/aws-sdk-go-v2/service/secretsmanager`: [v1.21.0](service/secretsmanager/CHANGELOG.md#v1210-2023-08-10) + * **Feature**: Add additional InvalidRequestException to list of possible exceptions for ListSecret. +* `github.com/aws/aws-sdk-go-v2/service/transfer`: [v1.33.3](service/transfer/CHANGELOG.md#v1333-2023-08-10) + * **Documentation**: Documentation updates for AW Transfer Family + +# Release (2023-08-09) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/chimesdkvoice`: [v1.8.0](service/chimesdkvoice/CHANGELOG.md#v180-2023-08-09) + * **Feature**: Updating CreatePhoneNumberOrder, UpdatePhoneNumber and BatchUpdatePhoneNumbers APIs, adding phone number name +* `github.com/aws/aws-sdk-go-v2/service/fsx`: [v1.32.0](service/fsx/CHANGELOG.md#v1320-2023-08-09) + * **Feature**: For FSx for Lustre, add new data repository task type, RELEASE_DATA_FROM_FILESYSTEM, to release files that have been archived to S3. For FSx for Windows, enable support for configuring and updating SSD IOPS, and for updating storage type. For FSx for OpenZFS, add new deployment type, MULTI_AZ_1. +* `github.com/aws/aws-sdk-go-v2/service/globalaccelerator`: [v1.17.3](service/globalaccelerator/CHANGELOG.md#v1173-2023-08-09) + * **Documentation**: Documentation update for dualstack EC2 endpoint support +* `github.com/aws/aws-sdk-go-v2/service/guardduty`: [v1.26.0](service/guardduty/CHANGELOG.md#v1260-2023-08-09) + * **Feature**: Added autoEnable ALL to UpdateOrganizationConfiguration and DescribeOrganizationConfiguration APIs. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.101.0](service/sagemaker/CHANGELOG.md#v11010-2023-08-09) + * **Feature**: This release adds support for cross account access for SageMaker Model Cards through AWS RAM. + +# Release (2023-08-08) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/backup`: [v1.24.0](service/backup/CHANGELOG.md#v1240-2023-08-08) + * **Feature**: This release introduces a new logically air-gapped vault (Preview) in AWS Backup that stores immutable backup copies, which are locked by default and isolated with encryption using AWS owned keys. Logically air-gapped vault (Preview) allows secure recovery of application data across accounts. +* `github.com/aws/aws-sdk-go-v2/service/elasticache`: [v1.29.0](service/elasticache/CHANGELOG.md#v1290-2023-08-08) + * **Feature**: Added support for cluster mode in online migration and test migration API +* `github.com/aws/aws-sdk-go-v2/service/servicecatalog`: [v1.21.0](service/servicecatalog/CHANGELOG.md#v1210-2023-08-08) + * **Feature**: Introduce support for HashiCorp Terraform Cloud in Service Catalog by addying TERRAFORM_CLOUD product type in CreateProduct and CreateProvisioningArtifact API. + +# Release (2023-08-07) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/detective`: [v1.21.0](service/detective/CHANGELOG.md#v1210-2023-08-07) + * **Feature**: Updated the email validation regex to be in line with the TLD name specifications. +* `github.com/aws/aws-sdk-go-v2/service/ivsrealtime`: [v1.4.0](service/ivsrealtime/CHANGELOG.md#v140-2023-08-07) + * **Feature**: Add QUOTA_EXCEEDED and PUBLISHER_NOT_FOUND to EventErrorCode for stage health events. +* `github.com/aws/aws-sdk-go-v2/service/kinesisvideo`: [v1.18.0](service/kinesisvideo/CHANGELOG.md#v1180-2023-08-07) + * **Feature**: This release enables minimum of Images SamplingInterval to be as low as 200 milliseconds in Kinesis Video Stream Image feature. +* `github.com/aws/aws-sdk-go-v2/service/kinesisvideoarchivedmedia`: [v1.16.0](service/kinesisvideoarchivedmedia/CHANGELOG.md#v1160-2023-08-07) + * **Feature**: This release enables minimum of Images SamplingInterval to be as low as 200 milliseconds in Kinesis Video Stream Image feature. +* `github.com/aws/aws-sdk-go-v2/service/rekognition`: [v1.30.2](service/rekognition/CHANGELOG.md#v1302-2023-08-07) + * **Documentation**: This release adds code snippets for Amazon Rekognition Custom Labels. + +# Release (2023-08-04) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/acmpca`: [v1.22.2](service/acmpca/CHANGELOG.md#v1222-2023-08-04) + * **Documentation**: Documentation correction for AWS Private CA +* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.64.0](service/connect/CHANGELOG.md#v1640-2023-08-04) + * **Feature**: Added a new API UpdateRoutingProfileAgentAvailabilityTimer to update agent availability timer of a routing profile. +* `github.com/aws/aws-sdk-go-v2/service/datasync`: [v1.28.0](service/datasync/CHANGELOG.md#v1280-2023-08-04) + * **Feature**: Display cloud storage used capacity at a cluster level. +* `github.com/aws/aws-sdk-go-v2/service/ecs`: [v1.29.2](service/ecs/CHANGELOG.md#v1292-2023-08-04) + * **Documentation**: This is a documentation update to address various tickets. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.100.0](service/sagemaker/CHANGELOG.md#v11000-2023-08-04) + * **Feature**: Including DataCaptureConfig key in the Amazon Sagemaker Search's transform job object + +# Release (2023-08-03) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/autoscaling`: [v1.30.2](service/autoscaling/CHANGELOG.md#v1302-2023-08-03) + * **Documentation**: Documentation changes related to Amazon EC2 Auto Scaling APIs. +* `github.com/aws/aws-sdk-go-v2/service/cloud9`: [v1.18.2](service/cloud9/CHANGELOG.md#v1182-2023-08-03) + * **Documentation**: Updated the deprecation date for Amazon Linux. Doc only update. +* `github.com/aws/aws-sdk-go-v2/service/databasemigrationservice`: [v1.30.0](service/databasemigrationservice/CHANGELOG.md#v1300-2023-08-03) + * **Feature**: The release makes public API for DMS Schema Conversion feature. +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.110.0](service/ec2/CHANGELOG.md#v11100-2023-08-03) + * **Feature**: This release adds new parameter isPrimaryIPv6 to allow assigning an IPv6 address as a primary IPv6 address to a network interface which cannot be changed to give equivalent functionality available for network interfaces with primary IPv4 address. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.99.0](service/sagemaker/CHANGELOG.md#v1990-2023-08-03) + * **Feature**: Amazon SageMaker now supports running training jobs on p5.48xlarge instance types. + +# Release (2023-08-02) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/budgets`: [v1.16.0](service/budgets/CHANGELOG.md#v1160-2023-08-02) + * **Feature**: As part of CAE tagging integration we need to update our budget names regex filter to prevent customers from using "/action/" in their budget names. +* `github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider`: [v1.25.0](service/cognitoidentityprovider/CHANGELOG.md#v1250-2023-08-02) + * **Feature**: New feature that logs Cognito user pool error messages to CloudWatch logs. +* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.60.0](service/glue/CHANGELOG.md#v1600-2023-08-02) + * **Feature**: This release includes additional Glue Streaming KAKFA SASL property types. +* `github.com/aws/aws-sdk-go-v2/service/resiliencehub`: [v1.13.0](service/resiliencehub/CHANGELOG.md#v1130-2023-08-02) + * **Feature**: Drift Detection capability added when applications policy has moved from a meet to breach state. Customers will be able to exclude operational recommendations and receive credit in their resilience score. Customers can now add ARH permissions to an existing or new role. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.98.0](service/sagemaker/CHANGELOG.md#v1980-2023-08-02) + * **Feature**: SageMaker Inference Recommender introduces a new API GetScalingConfigurationRecommendation to recommend auto scaling policies based on completed Inference Recommender jobs. + +# Release (2023-08-01) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/batch`: [v1.26.0](service/batch/CHANGELOG.md#v1260-2023-08-01) + * **Feature**: This release adds support for price capacity optimized allocation strategy for Spot Instances. +* `github.com/aws/aws-sdk-go-v2/service/databasemigrationservice`: [v1.29.0](service/databasemigrationservice/CHANGELOG.md#v1290-2023-08-01) + * **Feature**: Adding new API describe-engine-versions which provides information about the lifecycle of a replication instance's version. +* `github.com/aws/aws-sdk-go-v2/service/internetmonitor`: [v1.5.0](service/internetmonitor/CHANGELOG.md#v150-2023-08-01) + * **Feature**: This release adds a new feature for Amazon CloudWatch Internet Monitor that enables customers to set custom thresholds, for performance and availability drops, for impact limited to a single city-network to trigger creation of a health event. +* `github.com/aws/aws-sdk-go-v2/service/medialive`: [v1.34.0](service/medialive/CHANGELOG.md#v1340-2023-08-01) + * **Feature**: AWS Elemental Link devices now report their Availability Zone. Link devices now support the ability to change their Availability Zone. +* `github.com/aws/aws-sdk-go-v2/service/polly`: [v1.29.0](service/polly/CHANGELOG.md#v1290-2023-08-01) + * **Feature**: Amazon Polly adds new French Belgian voice - Isabelle. Isabelle is available as Neural voice only. +* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.50.0](service/rds/CHANGELOG.md#v1500-2023-08-01) + * **Feature**: Added support for deleted clusters PiTR. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.97.0](service/sagemaker/CHANGELOG.md#v1970-2023-08-01) + * **Feature**: Add Stairs TrafficPattern and FlatInvocations to RecommendationJobStoppingConditions + +# Release (2023-07-31) + +## General Highlights +* **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 + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/amplifyuibuilder`: [v1.12.0](service/amplifyuibuilder/CHANGELOG.md#v1120-2023-07-31) + * **Feature**: Amplify Studio releases GraphQL support for codegen job action. +* `github.com/aws/aws-sdk-go-v2/service/autoscaling`: [v1.30.0](service/autoscaling/CHANGELOG.md#v1300-2023-07-31) + * **Feature**: You can now configure an instance refresh to set its status to 'failed' when it detects that a specified CloudWatch alarm has gone into the ALARM state. You can also choose to roll back the instance refresh automatically when the alarm threshold is met. +* `github.com/aws/aws-sdk-go-v2/service/cleanrooms`: [v1.3.0](service/cleanrooms/CHANGELOG.md#v130-2023-07-31) + * **Feature**: This release introduces custom SQL queries - an expanded set of SQL you can run. This release adds analysis templates, a new resource for storing pre-defined custom SQL queries ahead of time. This release also adds the Custom analysis rule, which lets you approve analysis templates for querying. +* `github.com/aws/aws-sdk-go-v2/service/codestarconnections`: [v1.15.0](service/codestarconnections/CHANGELOG.md#v1150-2023-07-31) + * **Feature**: New integration with the Gitlab provider type. +* `github.com/aws/aws-sdk-go-v2/service/drs`: [v1.15.0](service/drs/CHANGELOG.md#v1150-2023-07-31) + * **Feature**: Add support for in-aws right sizing +* `github.com/aws/aws-sdk-go-v2/service/inspector2`: [v1.16.0](service/inspector2/CHANGELOG.md#v1160-2023-07-31) + * **Feature**: This release adds 1 new API: BatchGetFindingDetails to retrieve enhanced vulnerability intelligence details for findings. +* `github.com/aws/aws-sdk-go-v2/service/lookoutequipment`: [v1.18.0](service/lookoutequipment/CHANGELOG.md#v1180-2023-07-31) + * **Feature**: This release includes new import resource, model versioning and resource policy features. +* `github.com/aws/aws-sdk-go-v2/service/omics`: [v1.6.0](service/omics/CHANGELOG.md#v160-2023-07-31) + * **Feature**: Add CreationType filter for ListReadSets +* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.49.0](service/rds/CHANGELOG.md#v1490-2023-07-31) + * **Feature**: This release adds support for Aurora MySQL local write forwarding, which allows for forwarding of write operations from reader DB instances to the writer DB instance. +* `github.com/aws/aws-sdk-go-v2/service/route53`: [v1.29.0](service/route53/CHANGELOG.md#v1290-2023-07-31) + * **Feature**: Amazon Route 53 now supports the Israel (Tel Aviv) Region (il-central-1) for latency records, geoproximity records, and private DNS for Amazon VPCs in that region. +* `github.com/aws/aws-sdk-go-v2/service/scheduler`: [v1.2.0](service/scheduler/CHANGELOG.md#v120-2023-07-31) + * **Feature**: This release introduces automatic deletion of schedules in EventBridge Scheduler. If configured, EventBridge Scheduler automatically deletes a schedule after the schedule has completed its last invocation. + +# Release (2023-07-28.2) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/applicationinsights`: [v1.18.0](service/applicationinsights/CHANGELOG.md#v1180-2023-07-282) + * **Feature**: This release enable customer to add/remove/update more than one workload for a component +* `github.com/aws/aws-sdk-go-v2/service/cloudformation`: [v1.33.0](service/cloudformation/CHANGELOG.md#v1330-2023-07-282) + * **Feature**: This SDK release is for the feature launch of AWS CloudFormation RetainExceptOnCreate. It adds a new parameter retainExceptOnCreate in the following APIs: CreateStack, UpdateStack, RollbackStack, ExecuteChangeSet. +* `github.com/aws/aws-sdk-go-v2/service/cloudfront`: [v1.27.0](service/cloudfront/CHANGELOG.md#v1270-2023-07-282) + * **Feature**: Add a new JavaScript runtime version for CloudFront Functions. +* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.62.0](service/connect/CHANGELOG.md#v1620-2023-07-282) + * **Feature**: This release adds support for new number types. +* `github.com/aws/aws-sdk-go-v2/service/kafka`: [v1.21.0](service/kafka/CHANGELOG.md#v1210-2023-07-282) + * **Feature**: Amazon MSK has introduced new versions of ListClusterOperations and DescribeClusterOperation APIs. These v2 APIs provide information and insights into the ongoing operations of both MSK Provisioned and MSK Serverless clusters. +* `github.com/aws/aws-sdk-go-v2/service/pinpoint`: [v1.21.0](service/pinpoint/CHANGELOG.md#v1210-2023-07-282) + * **Feature**: Added support for sending push notifications using the FCM v1 API with json credentials. Amazon Pinpoint customers can now deliver messages to Android devices using both FCM v1 API and the legacy FCM/GCM API + +# Release (2023-07-28) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/sqs`: [v1.23.4](service/sqs/CHANGELOG.md#v1234-2023-07-28) + * **Documentation**: Documentation changes related to SQS APIs. + +# Release (2023-07-27) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/autoscaling`: [v1.29.0](service/autoscaling/CHANGELOG.md#v1290-2023-07-27) + * **Feature**: This release updates validation for instance types used in the AllowedInstanceTypes and ExcludedInstanceTypes parameters of the InstanceRequirements property of a MixedInstancesPolicy. +* `github.com/aws/aws-sdk-go-v2/service/ebs`: [v1.17.0](service/ebs/CHANGELOG.md#v1170-2023-07-27) + * **Feature**: SDK and documentation updates for Amazon Elastic Block Store API +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.108.0](service/ec2/CHANGELOG.md#v11080-2023-07-27) + * **Feature**: SDK and documentation updates for Amazon Elastic Block Store APIs +* `github.com/aws/aws-sdk-go-v2/service/eks`: [v1.28.0](service/eks/CHANGELOG.md#v1280-2023-07-27) + * **Feature**: Add multiple customer error code to handle customer caused failure when managing EKS node groups +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.95.0](service/sagemaker/CHANGELOG.md#v1950-2023-07-27) + * **Feature**: Expose ProfilerConfig attribute in SageMaker Search API response. + +# Release (2023-07-26) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/entityresolution`: [v1.0.0](service/entityresolution/CHANGELOG.md#v100-2023-07-26) + * **Release**: New AWS service client module + * **Feature**: AWS Entity Resolution can effectively match a source record from a customer relationship management (CRM) system with a source record from a marketing system containing campaign information. +* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.58.0](service/glue/CHANGELOG.md#v1580-2023-07-26) + * **Feature**: Release Glue Studio Snowflake Connector Node for SDK/CLI +* `github.com/aws/aws-sdk-go-v2/service/healthlake`: [v1.16.4](service/healthlake/CHANGELOG.md#v1164-2023-07-26) + * **Documentation**: Updating the HealthLake service documentation. +* `github.com/aws/aws-sdk-go-v2/service/managedblockchainquery`: [v1.0.0](service/managedblockchainquery/CHANGELOG.md#v100-2023-07-26) + * **Release**: New AWS service client module + * **Feature**: Amazon Managed Blockchain (AMB) Query provides serverless access to standardized, multi-blockchain datasets with developer-friendly APIs. +* `github.com/aws/aws-sdk-go-v2/service/mediaconvert`: [v1.39.1](service/mediaconvert/CHANGELOG.md#v1391-2023-07-26) + * **Documentation**: This release includes general updates to user documentation. +* `github.com/aws/aws-sdk-go-v2/service/omics`: [v1.5.2](service/omics/CHANGELOG.md#v152-2023-07-26) + * **Documentation**: The service is renaming as a part of AWS Health. +* `github.com/aws/aws-sdk-go-v2/service/opensearchserverless`: [v1.3.0](service/opensearchserverless/CHANGELOG.md#v130-2023-07-26) + * **Feature**: This release adds new collection type VectorSearch. +* `github.com/aws/aws-sdk-go-v2/service/polly`: [v1.27.0](service/polly/CHANGELOG.md#v1270-2023-07-26) + * **Feature**: Amazon Polly adds 1 new voice - Lisa (nl-BE) +* `github.com/aws/aws-sdk-go-v2/service/route53`: [v1.28.5](service/route53/CHANGELOG.md#v1285-2023-07-26) + * **Documentation**: Update that corrects the documents for received feedback. + +# Release (2023-07-25) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/billingconductor`: [v1.7.0](service/billingconductor/CHANGELOG.md#v170-2023-07-25) + * **Feature**: Added support for Auto-Assocate Billing Groups for CreateBillingGroup, UpdateBillingGroup, and ListBillingGroups. +* `github.com/aws/aws-sdk-go-v2/service/customerprofiles`: [v1.26.0](service/customerprofiles/CHANGELOG.md#v1260-2023-07-25) + * **Feature**: Amazon Connect Customer Profiles now supports rule-based resolution to match and merge similar profiles into unified profiles, helping companies deliver faster and more personalized customer service by providing access to relevant customer information for agents and automated experiences. +* `github.com/aws/aws-sdk-go-v2/service/datasync`: [v1.26.0](service/datasync/CHANGELOG.md#v1260-2023-07-25) + * **Feature**: AWS DataSync now supports Microsoft Azure Blob Storage locations. +* `github.com/aws/aws-sdk-go-v2/service/dynamodb`: [v1.20.2](service/dynamodb/CHANGELOG.md#v1202-2023-07-25) + * **Documentation**: Documentation updates for DynamoDB +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.107.0](service/ec2/CHANGELOG.md#v11070-2023-07-25) + * **Feature**: This release adds an instance's peak and baseline network bandwidth as well as the memory sizes of an instance's inference accelerators to DescribeInstanceTypes. +* `github.com/aws/aws-sdk-go-v2/service/emrserverless`: [v1.9.0](service/emrserverless/CHANGELOG.md#v190-2023-07-25) + * **Feature**: This release adds support for publishing application logs to CloudWatch. +* `github.com/aws/aws-sdk-go-v2/service/lambda`: [v1.38.0](service/lambda/CHANGELOG.md#v1380-2023-07-25) + * **Feature**: Add Python 3.11 (python3.11) support to AWS Lambda +* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.48.0](service/rds/CHANGELOG.md#v1480-2023-07-25) + * **Feature**: This release adds support for monitoring storage optimization progress on the DescribeDBInstances API. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.94.0](service/sagemaker/CHANGELOG.md#v1940-2023-07-25) + * **Feature**: Mark ContentColumn and TargetLabelColumn as required Targets in TextClassificationJobConfig in CreateAutoMLJobV2API +* `github.com/aws/aws-sdk-go-v2/service/securityhub`: [v1.34.0](service/securityhub/CHANGELOG.md#v1340-2023-07-25) + * **Feature**: Add support for CONTAINS and NOT_CONTAINS comparison operators for Automation Rules string filters and map filters +* `github.com/aws/aws-sdk-go-v2/service/sts`: [v1.20.0](service/sts/CHANGELOG.md#v1200-2023-07-25) + * **Feature**: API updates for the AWS Security Token Service +* `github.com/aws/aws-sdk-go-v2/service/transfer`: [v1.32.0](service/transfer/CHANGELOG.md#v1320-2023-07-25) + * **Feature**: This release adds support for SFTP Connectors. +* `github.com/aws/aws-sdk-go-v2/service/wisdom`: [v1.14.0](service/wisdom/CHANGELOG.md#v1140-2023-07-25) + * **Feature**: This release added two new data types: AssistantIntegrationConfiguration, and SessionIntegrationConfiguration to support Wisdom integration with Amazon Connect Chat + +# Release (2023-07-24) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/apigatewayv2`: [v1.13.15](service/apigatewayv2/CHANGELOG.md#v11315-2023-07-24) + * **Documentation**: Documentation updates for Amazon API Gateway. +* `github.com/aws/aws-sdk-go-v2/service/chimesdkmediapipelines`: [v1.5.0](service/chimesdkmediapipelines/CHANGELOG.md#v150-2023-07-24) + * **Feature**: AWS Media Pipeline compositing enhancement and Media Insights Pipeline auto language identification. +* `github.com/aws/aws-sdk-go-v2/service/cloudformation`: [v1.32.0](service/cloudformation/CHANGELOG.md#v1320-2023-07-24) + * **Feature**: This release supports filtering by DRIFT_STATUS for existing API ListStackInstances and adds support for a new API ListStackInstanceResourceDrifts. Customers can now view resource drift information from their StackSet management accounts. +* `github.com/aws/aws-sdk-go-v2/service/costexplorer`: [v1.26.0](service/costexplorer/CHANGELOG.md#v1260-2023-07-24) + * **Feature**: This release introduces the new API 'GetSavingsPlanPurchaseRecommendationDetails', which retrieves the details for a Savings Plan recommendation. It also updates the existing API 'GetSavingsPlansPurchaseRecommendation' to include the recommendation detail ID. +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.106.0](service/ec2/CHANGELOG.md#v11060-2023-07-24) + * **Feature**: Add "disabled" enum value to SpotInstanceState. +* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.57.0](service/glue/CHANGELOG.md#v1570-2023-07-24) + * **Feature**: Added support for Data Preparation Recipe node in Glue Studio jobs +* `github.com/aws/aws-sdk-go-v2/service/quicksight`: [v1.39.0](service/quicksight/CHANGELOG.md#v1390-2023-07-24) + * **Feature**: This release launches new Snapshot APIs for CSV and PDF exports, adds support for info icon for filters and parameters in Exploration APIs, adds modeled exception to the DeleteAccountCustomization API, and introduces AttributeAggregationFunction's ability to add UNIQUE_VALUE aggregation in tooltips. + +# Release (2023-07-21) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.56.0](service/glue/CHANGELOG.md#v1560-2023-07-21) + * **Feature**: This release adds support for AWS Glue Crawler with Apache Hudi Tables, allowing Crawlers to discover Hudi Tables in S3 and register them in Glue Data Catalog for query engines to query against. +* `github.com/aws/aws-sdk-go-v2/service/mediaconvert`: [v1.39.0](service/mediaconvert/CHANGELOG.md#v1390-2023-07-21) + * **Feature**: This release includes improvements to Preserve 444 handling, compatibility of HEVC sources without frame rates, and general improvements to MP4 outputs. +* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.47.0](service/rds/CHANGELOG.md#v1470-2023-07-21) + * **Feature**: Adds support for the DBSystemID parameter of CreateDBInstance to RDS Custom for Oracle. +* `github.com/aws/aws-sdk-go-v2/service/workspaces`: [v1.28.17](service/workspaces/CHANGELOG.md#v12817-2023-07-21) + * **Documentation**: Fixed VolumeEncryptionKey descriptions + +# Release (2023-07-20.2) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/codecatalyst`: [v1.4.0](service/codecatalyst/CHANGELOG.md#v140-2023-07-202) + * **Feature**: This release adds support for updating and deleting spaces and projects in Amazon CodeCatalyst. It also adds support for creating, getting, and deleting source repositories in CodeCatalyst projects. +* `github.com/aws/aws-sdk-go-v2/service/connectcases`: [v1.5.0](service/connectcases/CHANGELOG.md#v150-2023-07-202) + * **Feature**: This release adds the ability to assign a case to a queue or user. +* `github.com/aws/aws-sdk-go-v2/service/lexmodelsv2`: [v1.31.0](service/lexmodelsv2/CHANGELOG.md#v1310-2023-07-202) + * **Feature**: This release updates type for Channel field in SessionSpecification and UtteranceSpecification +* `github.com/aws/aws-sdk-go-v2/service/route53resolver`: [v1.18.0](service/route53resolver/CHANGELOG.md#v1180-2023-07-202) + * **Feature**: This release adds support for Route 53 On Outposts, a new feature that allows customers to run Route 53 Resolver and Resolver endpoints locally on their Outposts. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.93.0](service/sagemaker/CHANGELOG.md#v1930-2023-07-202) + * **Feature**: Cross account support for SageMaker Feature Store +* `github.com/aws/aws-sdk-go-v2/service/sagemakerfeaturestoreruntime`: [v1.16.0](service/sagemakerfeaturestoreruntime/CHANGELOG.md#v1160-2023-07-202) + * **Feature**: Cross account support for SageMaker Feature Store +* `github.com/aws/aws-sdk-go-v2/service/securitylake`: [v1.5.0](service/securitylake/CHANGELOG.md#v150-2023-07-202) + * **Feature**: Adding support for Tags on Create and Resource Tagging API. +* `github.com/aws/aws-sdk-go-v2/service/transcribe`: [v1.27.0](service/transcribe/CHANGELOG.md#v1270-2023-07-202) + * **Feature**: Added API argument --toxicity-detection to startTranscriptionJob API, which allows users to view toxicity scores of submitted audio. + +# Release (2023-07-20) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/savingsplans`: [v1.12.14](service/savingsplans/CHANGELOG.md#v11214-2023-07-20) + * **Documentation**: Savings Plans endpoints update + +# Release (2023-07-19) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/cloudformation`: [v1.31.0](service/cloudformation/CHANGELOG.md#v1310-2023-07-19) + * **Feature**: SDK and documentation updates for GetTemplateSummary API (unrecognized resources) +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.105.1](service/ec2/CHANGELOG.md#v11051-2023-07-19) + * **Documentation**: Amazon EC2 documentation updates. +* `github.com/aws/aws-sdk-go-v2/service/grafana`: [v1.14.0](service/grafana/CHANGELOG.md#v1140-2023-07-19) + * **Feature**: Amazon Managed Grafana now supports grafanaVersion update for existing workspaces with UpdateWorkspaceConfiguration API. DescribeWorkspaceConfiguration API additionally returns grafanaVersion. A new ListVersions API lists available versions or, if given a workspaceId, the versions it can upgrade to. +* `github.com/aws/aws-sdk-go-v2/service/medicalimaging`: [v1.0.0](service/medicalimaging/CHANGELOG.md#v100-2023-07-19) + * **Release**: New AWS service client module + * **Feature**: General Availability (GA) release of AWS Health Imaging, enabling customers to store, transform, and analyze medical imaging data at petabyte-scale. +* `github.com/aws/aws-sdk-go-v2/service/ram`: [v1.19.0](service/ram/CHANGELOG.md#v1190-2023-07-19) + * **Feature**: This release adds support for securely sharing with AWS service principals. +* `github.com/aws/aws-sdk-go-v2/service/ssmsap`: [v1.3.0](service/ssmsap/CHANGELOG.md#v130-2023-07-19) + * **Feature**: Added support for SAP Hana High Availability discovery (primary and secondary nodes) and Backint agent installation with SSM for SAP. +* `github.com/aws/aws-sdk-go-v2/service/wafv2`: [v1.36.0](service/wafv2/CHANGELOG.md#v1360-2023-07-19) + * **Feature**: Added the URI path to the custom aggregation keys that you can specify for a rate-based rule. + +# Release (2023-07-18) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/codegurusecurity`: [v1.0.3](service/codegurusecurity/CHANGELOG.md#v103-2023-07-18) + * **Documentation**: Documentation updates for CodeGuru Security. +* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.61.1](service/connect/CHANGELOG.md#v1611-2023-07-18) + * **Documentation**: GetMetricDataV2 API: Update to include Contact Lens Conversational Analytics Metrics +* `github.com/aws/aws-sdk-go-v2/service/lexmodelsv2`: [v1.30.0](service/lexmodelsv2/CHANGELOG.md#v1300-2023-07-18) + * **Feature**: This release adds support for Lex Developers to view analytics for their bots. +* `github.com/aws/aws-sdk-go-v2/service/m2`: [v1.6.0](service/m2/CHANGELOG.md#v160-2023-07-18) + * **Feature**: Allows UpdateEnvironment to update the environment to 0 host capacity. New GetSignedBluinsightsUrl API +* `github.com/aws/aws-sdk-go-v2/service/snowball`: [v1.20.0](service/snowball/CHANGELOG.md#v1200-2023-07-18) + * **Feature**: Adds support for RACK_5U_C. This is the first AWS Snow Family device designed to meet U.S. Military Ruggedization Standards (MIL-STD-810H) with 208 vCPU device in a portable, compact 5U, half-rack width form-factor. +* `github.com/aws/aws-sdk-go-v2/service/translate`: [v1.18.4](service/translate/CHANGELOG.md#v1184-2023-07-18) + * **Documentation**: Added DOCX word document support to TranslateDocument API + +# Release (2023-07-17) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/codeartifact`: [v1.18.8](service/codeartifact/CHANGELOG.md#v1188-2023-07-17) + * **Documentation**: Doc only update for AWS CodeArtifact +* `github.com/aws/aws-sdk-go-v2/service/docdb`: [v1.22.0](service/docdb/CHANGELOG.md#v1220-2023-07-17) + * **Feature**: Added major version upgrade option in ModifyDBCluster API +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.105.0](service/ec2/CHANGELOG.md#v11050-2023-07-17) + * **Feature**: Add Nitro TPM support on DescribeInstanceTypes +* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.55.0](service/glue/CHANGELOG.md#v1550-2023-07-17) + * **Feature**: Adding new supported permission type flags to get-unfiltered endpoints that callers may pass to indicate support for enforcing Lake Formation fine-grained access control on nested column attributes. +* `github.com/aws/aws-sdk-go-v2/service/ivs`: [v1.24.0](service/ivs/CHANGELOG.md#v1240-2023-07-17) + * **Feature**: This release provides the flexibility to configure what renditions or thumbnail qualities to record when creating recording configuration. +* `github.com/aws/aws-sdk-go-v2/service/lakeformation`: [v1.22.0](service/lakeformation/CHANGELOG.md#v1220-2023-07-17) + * **Feature**: Adds supports for ReadOnlyAdmins and AllowFullTableExternalDataAccess. Adds NESTED_PERMISSION and NESTED_CELL_PERMISSION to SUPPORTED_PERMISSION_TYPES enum. Adds CREATE_LF_TAG on catalog resource and ALTER, DROP, and GRANT_WITH_LF_TAG_EXPRESSION on LF Tag resource. + +# Release (2023-07-13) + +## General Highlights +* **Feature**: Modify user agent syntax and introduce support for optional app identifier in UA header +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider`: [v1.23.0](service/cognitoidentityprovider/CHANGELOG.md#v1230-2023-07-13) + * **Feature**: API model updated in Amazon Cognito +* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.61.0](service/connect/CHANGELOG.md#v1610-2023-07-13) + * **Feature**: Add support for deleting Queues and Routing Profiles. +* `github.com/aws/aws-sdk-go-v2/service/databasemigrationservice`: [v1.27.0](service/databasemigrationservice/CHANGELOG.md#v1270-2023-07-13) + * **Feature**: Enhanced PostgreSQL target endpoint settings for providing Babelfish support. +* `github.com/aws/aws-sdk-go-v2/service/datasync`: [v1.25.0](service/datasync/CHANGELOG.md#v1250-2023-07-13) + * **Feature**: Added LunCount to the response object of DescribeStorageSystemResourcesResponse, LunCount represents the number of LUNs on a storage system resource. +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.104.0](service/ec2/CHANGELOG.md#v11040-2023-07-13) + * **Feature**: This release adds support for the C7gn and Hpc7g instances. C7gn instances are powered by AWS Graviton3 processors and the fifth-generation AWS Nitro Cards. Hpc7g instances are powered by AWS Graviton 3E processors and provide up to 200 Gbps network bandwidth. +* `github.com/aws/aws-sdk-go-v2/service/fsx`: [v1.30.0](service/fsx/CHANGELOG.md#v1300-2023-07-13) + * **Feature**: Amazon FSx for NetApp ONTAP now supports SnapLock, an ONTAP feature that enables you to protect your files in a volume by transitioning them to a write once, read many (WORM) state. +* `github.com/aws/aws-sdk-go-v2/service/iam`: [v1.21.1](service/iam/CHANGELOG.md#v1211-2023-07-13) + * **Documentation**: Documentation updates for AWS Identity and Access Management (IAM). +* `github.com/aws/aws-sdk-go-v2/service/mediatailor`: [v1.25.0](service/mediatailor/CHANGELOG.md#v1250-2023-07-13) + * **Feature**: Adds categories to MediaTailor channel assembly alerts +* `github.com/aws/aws-sdk-go-v2/service/personalize`: [v1.25.0](service/personalize/CHANGELOG.md#v1250-2023-07-13) + * **Feature**: This release provides ability to customers to change schema associated with their datasets in Amazon Personalize +* `github.com/aws/aws-sdk-go-v2/service/proton`: [v1.22.0](service/proton/CHANGELOG.md#v1220-2023-07-13) + * **Feature**: This release adds support for deployment history for Proton provisioned resources +* `github.com/aws/aws-sdk-go-v2/service/s3`: [v1.37.0](service/s3/CHANGELOG.md#v1370-2023-07-13) + * **Feature**: S3 Inventory now supports Object Access Control List and Object Owner as available object metadata fields in inventory reports. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.92.0](service/sagemaker/CHANGELOG.md#v1920-2023-07-13) + * **Feature**: Amazon SageMaker Canvas adds WorkspeceSettings support for CanvasAppSettings +* `github.com/aws/aws-sdk-go-v2/service/secretsmanager`: [v1.19.11](service/secretsmanager/CHANGELOG.md#v11911-2023-07-13) + * **Documentation**: Documentation updates for Secrets Manager + +# Release (2023-07-07) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs`: [v1.22.0](service/cloudwatchlogs/CHANGELOG.md#v1220-2023-07-07) + * **Feature**: Add CMK encryption support for CloudWatch Logs Insights query result data +* `github.com/aws/aws-sdk-go-v2/service/databasemigrationservice`: [v1.26.0](service/databasemigrationservice/CHANGELOG.md#v1260-2023-07-07) + * **Feature**: Releasing DMS Serverless. Adding support for PostgreSQL 15.x as source and target endpoint. Adding support for DocDB Elastic Clusters with sharded collections, PostgreSQL datatype mapping customization and disabling hostname validation of the certificate authority in Kafka endpoint settings +* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.54.0](service/glue/CHANGELOG.md#v1540-2023-07-07) + * **Feature**: This release enables customers to create new Apache Iceberg tables and associated metadata in Amazon S3 by using native AWS Glue CreateTable operation. +* `github.com/aws/aws-sdk-go-v2/service/medialive`: [v1.32.0](service/medialive/CHANGELOG.md#v1320-2023-07-07) + * **Feature**: This release enables the use of Thumbnails in AWS Elemental MediaLive. +* `github.com/aws/aws-sdk-go-v2/service/mediatailor`: [v1.24.0](service/mediatailor/CHANGELOG.md#v1240-2023-07-07) + * **Feature**: The AWS Elemental MediaTailor SDK for Channel Assembly has added support for EXT-X-CUE-OUT and EXT-X-CUE-IN tags to specify ad breaks in HLS outputs, including support for EXT-OATCLS, EXT-X-ASSET, and EXT-X-CUE-OUT-CONT accessory tags. + +# Release (2023-07-06) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.103.0](service/ec2/CHANGELOG.md#v11030-2023-07-06) + * **Feature**: Add Nitro Enclaves support on DescribeInstanceTypes +* `github.com/aws/aws-sdk-go-v2/service/location`: [v1.25.0](service/location/CHANGELOG.md#v1250-2023-07-06) + * **Feature**: This release adds support for authenticating with Amazon Location Service's Places & Routes APIs with an API Key. Also, with this release developers can publish tracked device position updates to Amazon EventBridge. +* `github.com/aws/aws-sdk-go-v2/service/outposts`: [v1.28.0](service/outposts/CHANGELOG.md#v1280-2023-07-06) + * **Feature**: Added paginator support to several APIs. Added the ISOLATED enum value to AssetState. +* `github.com/aws/aws-sdk-go-v2/service/quicksight`: [v1.38.0](service/quicksight/CHANGELOG.md#v1380-2023-07-06) + * **Feature**: This release includes below three changes: small multiples axes improvement, field based coloring, removed required trait from Aggregation function for TopBottomFilter. +* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.46.1](service/rds/CHANGELOG.md#v1461-2023-07-06) + * **Documentation**: Updates Amazon RDS documentation for creating DB instances and creating Aurora global clusters. + +# Release (2023-07-05) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/comprehendmedical`: [v1.16.3](service/comprehendmedical/CHANGELOG.md#v1163-2023-07-05) + * **Documentation**: Update to Amazon Comprehend Medical documentation. +* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.60.1](service/connect/CHANGELOG.md#v1601-2023-07-05) + * **Documentation**: GetMetricDataV2 API: Channels filters do not count towards overall limitation of 100 filter values. +* `github.com/aws/aws-sdk-go-v2/service/kms`: [v1.23.0](service/kms/CHANGELOG.md#v1230-2023-07-05) + * **Feature**: Added Dry Run Feature to cryptographic and cross-account mutating KMS APIs (14 in all). This feature allows users to test their permissions and parameters before making the actual API call. +* `github.com/aws/aws-sdk-go-v2/service/mgn`: [v1.19.0](service/mgn/CHANGELOG.md#v1190-2023-07-05) + * **Feature**: This release introduces the Global view feature and new Replication state APIs. +* `github.com/aws/aws-sdk-go-v2/service/securityhub`: [v1.33.2](service/securityhub/CHANGELOG.md#v1332-2023-07-05) + * **Documentation**: Documentation updates for AWS Security Hub + +# Release (2023-07-03) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/batch`: [v1.24.0](service/batch/CHANGELOG.md#v1240-2023-07-03) + * **Feature**: This feature allows customers to use AWS Batch with Linux with ARM64 CPU Architecture and X86_64 CPU Architecture with Windows OS on Fargate Platform. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.91.0](service/sagemaker/CHANGELOG.md#v1910-2023-07-03) + * **Feature**: SageMaker Inference Recommender now accepts new fields SupportedEndpointType and ServerlessConfiguration to support serverless endpoints. + +# Release (2023-06-30) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/ecs`: [v1.28.0](service/ecs/CHANGELOG.md#v1280-2023-06-30) + * **Feature**: Added new field "credentialspecs" to the ecs task definition to support gMSA of windows/linux in both domainless and domain-joined mode +* `github.com/aws/aws-sdk-go-v2/service/mediaconvert`: [v1.38.1](service/mediaconvert/CHANGELOG.md#v1381-2023-06-30) + * **Documentation**: This release includes improved color handling of overlays and general updates to user documentation. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.90.0](service/sagemaker/CHANGELOG.md#v1900-2023-06-30) + * **Feature**: This release adds support for rolling deployment in SageMaker Inference. +* `github.com/aws/aws-sdk-go-v2/service/transfer`: [v1.31.0](service/transfer/CHANGELOG.md#v1310-2023-06-30) + * **Feature**: Add outbound Basic authentication support to AS2 connectors +* `github.com/aws/aws-sdk-go-v2/service/verifiedpermissions`: [v1.0.4](service/verifiedpermissions/CHANGELOG.md#v104-2023-06-30) + * **Documentation**: This release corrects several broken links in the documentation. + +# Release (2023-06-29) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/appstream`: [v1.21.0](service/appstream/CHANGELOG.md#v1210-2023-06-29) + * **Feature**: This release introduces app block builder, allowing customers to provision a resource to package applications into an app block +* `github.com/aws/aws-sdk-go-v2/service/chime`: [v1.24.0](service/chime/CHANGELOG.md#v1240-2023-06-29) + * **Feature**: The Amazon Chime SDK APIs in the Chime namespace are no longer supported. Customers should use APIs in the dedicated Amazon Chime SDK namespaces: ChimeSDKIdentity, ChimeSDKMediaPipelines, ChimeSDKMeetings, ChimeSDKMessaging, and ChimeSDKVoice. +* `github.com/aws/aws-sdk-go-v2/service/cleanrooms`: [v1.2.0](service/cleanrooms/CHANGELOG.md#v120-2023-06-29) + * **Feature**: This release adds support for the OR operator in RSQL join match conditions and the ability to control which operators (AND, OR) are allowed in a join match condition. +* `github.com/aws/aws-sdk-go-v2/service/dynamodb`: [v1.20.0](service/dynamodb/CHANGELOG.md#v1200-2023-06-29) + * **Feature**: This release adds ReturnValuesOnConditionCheckFailure parameter to PutItem, UpdateItem, DeleteItem, ExecuteStatement, BatchExecuteStatement and ExecuteTransaction APIs. When set to ALL_OLD, API returns a copy of the item as it was when a conditional write failed +* `github.com/aws/aws-sdk-go-v2/service/gamelift`: [v1.20.0](service/gamelift/CHANGELOG.md#v1200-2023-06-29) + * **Feature**: Amazon GameLift now supports game builds that use the Amazon Linux 2023 (AL2023) operating system. +* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.53.0](service/glue/CHANGELOG.md#v1530-2023-06-29) + * **Feature**: This release adds support for AWS Glue Crawler with Iceberg Tables, allowing Crawlers to discover Iceberg Tables in S3 and register them in Glue Data Catalog for query engines to query against. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.89.0](service/sagemaker/CHANGELOG.md#v1890-2023-06-29) + * **Feature**: Adding support for timeseries forecasting in the CreateAutoMLJobV2 API. + +# Release (2023-06-28) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/internetmonitor`: [v1.3.0](service/internetmonitor/CHANGELOG.md#v130-2023-06-28) + * **Feature**: This release adds a new feature for Amazon CloudWatch Internet Monitor that enables customers to set custom thresholds, for performance and availability drops, for triggering when to create a health event. +* `github.com/aws/aws-sdk-go-v2/service/kinesisanalyticsv2`: [v1.17.0](service/kinesisanalyticsv2/CHANGELOG.md#v1170-2023-06-28) + * **Feature**: Support for new runtime environment in Kinesis Data Analytics Studio: Zeppelin-0.10, Apache Flink-1.15 +* `github.com/aws/aws-sdk-go-v2/service/lambda`: [v1.37.0](service/lambda/CHANGELOG.md#v1370-2023-06-28) + * **Feature**: Surface ResourceConflictException in DeleteEventSourceMapping +* `github.com/aws/aws-sdk-go-v2/service/omics`: [v1.5.0](service/omics/CHANGELOG.md#v150-2023-06-28) + * **Feature**: Add Common Workflow Language (CWL) as a supported language for Omics workflows +* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.46.0](service/rds/CHANGELOG.md#v1460-2023-06-28) + * **Feature**: Amazon Relational Database Service (RDS) now supports joining a RDS for SQL Server instance to a self-managed Active Directory. +* `github.com/aws/aws-sdk-go-v2/service/s3`: [v1.36.0](service/s3/CHANGELOG.md#v1360-2023-06-28) + * **Feature**: The S3 LISTObjects, ListObjectsV2 and ListObjectVersions API now supports a new optional header x-amz-optional-object-attributes. If header contains RestoreStatus as the value, then S3 will include Glacier restore status i.e. isRestoreInProgress and RestoreExpiryDate in List response. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.88.0](service/sagemaker/CHANGELOG.md#v1880-2023-06-28) + * **Feature**: This release adds support for Model Cards Model Registry integration. + +# Release (2023-06-27) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/appfabric`: [v1.0.0](service/appfabric/CHANGELOG.md#v100-2023-06-27) + * **Release**: New AWS service client module + * **Feature**: Initial release of AWS AppFabric for connecting SaaS applications for better productivity and security. +* `github.com/aws/aws-sdk-go-v2/service/appflow`: [v1.32.0](service/appflow/CHANGELOG.md#v1320-2023-06-27) + * **Feature**: This release adds support to bypass SSO with the SAPOData connector when connecting to an SAP instance. +* `github.com/aws/aws-sdk-go-v2/service/emrserverless`: [v1.8.0](service/emrserverless/CHANGELOG.md#v180-2023-06-27) + * **Feature**: This release adds support to update the release label of an EMR Serverless application to upgrade it to a different version of Amazon EMR via UpdateApplication API. +* `github.com/aws/aws-sdk-go-v2/service/ivs`: [v1.23.0](service/ivs/CHANGELOG.md#v1230-2023-06-27) + * **Feature**: IVS customers can now revoke the viewer session associated with an auth token, to prevent and stop playback using that token. +* `github.com/aws/aws-sdk-go-v2/service/kinesisvideo`: [v1.16.0](service/kinesisvideo/CHANGELOG.md#v1160-2023-06-27) + * **Feature**: General Availability (GA) release of Kinesis Video Streams at Edge, enabling customers to provide a configuration for the Kinesis Video Streams EdgeAgent running on an on-premise IoT device. Customers can now locally record from cameras and stream videos to the cloud on a configured schedule. +* `github.com/aws/aws-sdk-go-v2/service/macie2`: [v1.28.0](service/macie2/CHANGELOG.md#v1280-2023-06-27) + * **Feature**: This release adds support for configuring new classification jobs to use the set of managed data identifiers that we recommend for jobs. For the managed data identifier selection type (managedDataIdentifierSelector), specify RECOMMENDED. +* `github.com/aws/aws-sdk-go-v2/service/privatenetworks`: [v1.3.0](service/privatenetworks/CHANGELOG.md#v130-2023-06-27) + * **Feature**: This release allows Private5G customers to choose different commitment plans (60-days, 1-year, 3-years) when placing new orders, enables automatic renewal option for 1-year and 3-years commitments. It also allows customers to update the commitment plan of an existing radio unit. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.87.0](service/sagemaker/CHANGELOG.md#v1870-2023-06-27) + * **Feature**: Introducing TTL for online store records in feature groups. +* `github.com/aws/aws-sdk-go-v2/service/sagemakerfeaturestoreruntime`: [v1.15.0](service/sagemakerfeaturestoreruntime/CHANGELOG.md#v1150-2023-06-27) + * **Feature**: Introducing TTL for online store records for feature groups. +* `github.com/aws/aws-sdk-go-v2/service/ssm`: [v1.36.7](service/ssm/CHANGELOG.md#v1367-2023-06-27) + * **Documentation**: Systems Manager doc-only update for June 2023. +* `github.com/aws/aws-sdk-go-v2/service/verifiedpermissions`: [v1.0.3](service/verifiedpermissions/CHANGELOG.md#v103-2023-06-27) + * **Documentation**: This update fixes several broken links to the Cedar documentation. + +# Release (2023-06-26) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.60.0](service/connect/CHANGELOG.md#v1600-2023-06-26) + * **Feature**: This release provides a way to search for existing tags within an instance. Before tagging a resource, ensure consistency by searching for pre-existing key:value pairs. +* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.52.0](service/glue/CHANGELOG.md#v1520-2023-06-26) + * **Feature**: Timestamp Starting Position For Kinesis and Kafka Data Sources in a Glue Streaming Job +* `github.com/aws/aws-sdk-go-v2/service/guardduty`: [v1.24.0](service/guardduty/CHANGELOG.md#v1240-2023-06-26) + * **Feature**: Add support for user.extra.sessionName in Kubernetes Audit Logs Findings. +* `github.com/aws/aws-sdk-go-v2/service/iam`: [v1.21.0](service/iam/CHANGELOG.md#v1210-2023-06-26) + * **Feature**: Support for a new API "GetMFADevice" to present MFA device metadata such as device certifications +* `github.com/aws/aws-sdk-go-v2/service/pinpoint`: [v1.20.0](service/pinpoint/CHANGELOG.md#v1200-2023-06-26) + * **Feature**: Added time zone estimation support for journeys + +# Release (2023-06-23) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/devopsguru`: [v1.24.0](service/devopsguru/CHANGELOG.md#v1240-2023-06-23) + * **Feature**: This release adds support for encryption via customer managed keys. +* `github.com/aws/aws-sdk-go-v2/service/fsx`: [v1.29.3](service/fsx/CHANGELOG.md#v1293-2023-06-23) + * **Documentation**: Update to Amazon FSx documentation. +* `github.com/aws/aws-sdk-go-v2/service/rds`: [v1.45.3](service/rds/CHANGELOG.md#v1453-2023-06-23) + * **Documentation**: Documentation improvements for create, describe, and modify DB clusters and DB instances. +* `github.com/aws/aws-sdk-go-v2/service/verifiedpermissions`: [v1.0.2](service/verifiedpermissions/CHANGELOG.md#v102-2023-06-23) + * **Documentation**: Added improved descriptions and new code samples to SDK documentation. + +# Release (2023-06-22) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/chimesdkidentity`: [v1.12.0](service/chimesdkidentity/CHANGELOG.md#v1120-2023-06-22) + * **Feature**: AppInstanceBots can be configured to be invoked or not using the Target or the CHIME.mentions attribute for ChannelMessages +* `github.com/aws/aws-sdk-go-v2/service/chimesdkmessaging`: [v1.16.0](service/chimesdkmessaging/CHANGELOG.md#v1160-2023-06-22) + * **Feature**: ChannelMessages can be made visible to sender and intended recipient rather than all channel members with the target attribute. For example, a user can send messages to a bot and receive messages back in a group channel without other members seeing them. +* `github.com/aws/aws-sdk-go-v2/service/kendra`: [v1.41.0](service/kendra/CHANGELOG.md#v1410-2023-06-22) + * **Feature**: Introducing Amazon Kendra Retrieve API that can be used to retrieve relevant passages or text excerpts given an input query. +* `github.com/aws/aws-sdk-go-v2/service/sfn`: [v1.18.0](service/sfn/CHANGELOG.md#v1180-2023-06-22) + * **Feature**: Adds support for Versions and Aliases. Adds 8 operations: PublishStateMachineVersion, DeleteStateMachineVersion, ListStateMachineVersions, CreateStateMachineAlias, DescribeStateMachineAlias, UpdateStateMachineAlias, DeleteStateMachineAlias, ListStateMachineAliases + +# Release (2023-06-21) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/dynamodb`: [v1.19.11](service/dynamodb/CHANGELOG.md#v11911-2023-06-21) + * **Documentation**: Documentation updates for DynamoDB +* `github.com/aws/aws-sdk-go-v2/service/emr`: [v1.27.0](service/emr/CHANGELOG.md#v1270-2023-06-21) + * **Feature**: This release introduces a new Amazon EMR EPI called ListSupportedInstanceTypes that returns a list of all instance types supported by a given EMR release. +* `github.com/aws/aws-sdk-go-v2/service/inspector2`: [v1.15.0](service/inspector2/CHANGELOG.md#v1150-2023-06-21) + * **Feature**: This release adds support for Software Bill of Materials (SBOM) export and the general availability of code scanning for AWS Lambda functions. +* `github.com/aws/aws-sdk-go-v2/service/mediaconvert`: [v1.38.0](service/mediaconvert/CHANGELOG.md#v1380-2023-06-21) + * **Feature**: This release introduces the bandwidth reduction filter for the HEVC encoder, increases the limits of outputs per job, and updates support for the Nagra SDK to version 1.14.7. +* `github.com/aws/aws-sdk-go-v2/service/mq`: [v1.15.0](service/mq/CHANGELOG.md#v1150-2023-06-21) + * **Feature**: The Cross Region Disaster Recovery feature allows to replicate a brokers state from one region to another in order to provide customers with multi-region resiliency in the event of a regional outage. +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.86.0](service/sagemaker/CHANGELOG.md#v1860-2023-06-21) + * **Feature**: This release provides support in SageMaker for output files in training jobs to be uploaded without compression and enable customer to deploy uncompressed model from S3 to real-time inference Endpoints. In addition, ml.trn1n.32xlarge is added to supported instance type list in training job. +* `github.com/aws/aws-sdk-go-v2/service/transfer`: [v1.30.0](service/transfer/CHANGELOG.md#v1300-2023-06-21) + * **Feature**: This release adds a new parameter StructuredLogDestinations to CreateServer, UpdateServer APIs. + +# Release (2023-06-20) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/appflow`: [v1.31.0](service/appflow/CHANGELOG.md#v1310-2023-06-20) + * **Feature**: This release adds new API to reset connector metadata cache +* `github.com/aws/aws-sdk-go-v2/service/configservice`: [v1.34.0](service/configservice/CHANGELOG.md#v1340-2023-06-20) + * **Feature**: Updated ResourceType enum with new resource types onboarded by AWS Config in May 2023. +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.102.0](service/ec2/CHANGELOG.md#v11020-2023-06-20) + * **Feature**: Adds support for targeting Dedicated Host allocations by assetIds in AWS Outposts +* `github.com/aws/aws-sdk-go-v2/service/lambda`: [v1.36.0](service/lambda/CHANGELOG.md#v1360-2023-06-20) + * **Feature**: This release adds RecursiveInvocationException to the Invoke API and InvokeWithResponseStream API. +* `github.com/aws/aws-sdk-go-v2/service/redshift`: [v1.28.0](service/redshift/CHANGELOG.md#v1280-2023-06-20) + * **Feature**: Added support for custom domain names for Redshift Provisioned clusters. This feature enables customers to create a custom domain name and use ACM to generate fully secure connections to it. + +# Release (2023-06-19) + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/cloudformation`: [v1.30.0](service/cloudformation/CHANGELOG.md#v1300-2023-06-19) + * **Feature**: Specify desired CloudFormation behavior in the event of ChangeSet execution failure using the CreateChangeSet OnStackFailure parameter +* `github.com/aws/aws-sdk-go-v2/service/ec2`: [v1.101.0](service/ec2/CHANGELOG.md#v11010-2023-06-19) + * **Feature**: API changes to AWS Verified Access to include data from trust providers in logs +* `github.com/aws/aws-sdk-go-v2/service/ecs`: [v1.27.4](service/ecs/CHANGELOG.md#v1274-2023-06-19) + * **Documentation**: Documentation only update to address various tickets. +* `github.com/aws/aws-sdk-go-v2/service/glue`: [v1.51.0](service/glue/CHANGELOG.md#v1510-2023-06-19) + * **Feature**: This release adds support for creating cross region table/database resource links +* `github.com/aws/aws-sdk-go-v2/service/pricing`: [v1.20.0](service/pricing/CHANGELOG.md#v1200-2023-06-19) + * **Feature**: This release updates the PriceListArn regex pattern. +* `github.com/aws/aws-sdk-go-v2/service/route53domains`: [v1.15.0](service/route53domains/CHANGELOG.md#v1150-2023-06-19) + * **Feature**: Update MaxItems upper bound to 1000 for ListPricesRequest +* `github.com/aws/aws-sdk-go-v2/service/sagemaker`: [v1.85.0](service/sagemaker/CHANGELOG.md#v1850-2023-06-19) + * **Feature**: Amazon Sagemaker Autopilot releases CreateAutoMLJobV2 and DescribeAutoMLJobV2 for Autopilot customers with ImageClassification, TextClassification and Tabular problem type config support. + +# Release (2023-06-16) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/applicationdiscoveryservice`: [v1.16.0](service/applicationdiscoveryservice/CHANGELOG.md#v1160-2023-06-16) + * **Feature**: Add Amazon EC2 instance recommendations export +* `github.com/aws/aws-sdk-go-v2/service/connect`: [v1.59.0](service/connect/CHANGELOG.md#v1590-2023-06-16) + * **Feature**: Updates the *InstanceStorageConfig APIs to support a new ResourceType: SCREEN_RECORDINGS to enable screen recording and specify the storage configurations for publishing the recordings. Also updates DescribeInstance and ListInstances APIs to include InstanceAccessUrl attribute in the API response. +* `github.com/aws/aws-sdk-go-v2/service/iam`: [v1.20.3](service/iam/CHANGELOG.md#v1203-2023-06-16) + * **Documentation**: Documentation updates for AWS Identity and Access Management (IAM). +* `github.com/aws/aws-sdk-go-v2/service/s3`: [v1.35.0](service/s3/CHANGELOG.md#v1350-2023-06-16) + * **Feature**: This release adds SDK support for request-payer request header and request-charged response header in the "GetBucketAccelerateConfiguration", "ListMultipartUploads", "ListObjects", "ListObjectsV2" and "ListObjectVersions" S3 APIs. + +# Release (2023-06-15) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/aws-sdk-go-v2/service/auditmanager`: [v1.25.0](service/auditmanager/CHANGELOG.md#v1250-2023-06-15) + * **Feature**: This release introduces 2 Audit Manager features: CSV exports and new manual evidence options. You can now export your evidence finder results in CSV format. In addition, you can now add manual evidence to a control by entering free-form text or uploading a file from your browser. +* `github.com/aws/aws-sdk-go-v2/service/efs`: [v1.20.3](service/efs/CHANGELOG.md#v1203-2023-06-15) + * **Documentation**: Documentation updates for EFS. +* `github.com/aws/aws-sdk-go-v2/service/guardduty`: [v1.23.2](service/guardduty/CHANGELOG.md#v1232-2023-06-15) + * **Documentation**: Updated descriptions for some APIs. +* `github.com/aws/aws-sdk-go-v2/service/location`: [v1.24.0](service/location/CHANGELOG.md#v1240-2023-06-15) + * **Feature**: Amazon Location Service adds categories to places, including filtering on those categories in searches. Also, you can now add metadata properties to your geofences. + # Release (2023-06-13) ## General Highlights diff --git a/vendor/github.com/aws/aws-sdk-go-v2/Makefile b/vendor/github.com/aws/aws-sdk-go-v2/Makefile index 4f74a2654..9dc36fe4e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/Makefile +++ b/vendor/github.com/aws/aws-sdk-go-v2/Makefile @@ -1,6 +1,9 @@ # Lint rules to ignore LINTIGNORESINGLEFIGHT='internal/sync/singleflight/singleflight.go:.+error should be the last type' LINT_IGNORE_S3MANAGER_INPUT='feature/s3/manager/upload.go:.+struct field SSEKMSKeyId should be SSEKMSKeyID' +# Names of these are tied to endpoint rules and they're internal so ignore them +LINT_IGNORE_AWSRULESFN_ARN='internal/endpoints/awsrulesfn/arn.go' +LINT_IGNORE_AWSRULESFN_PARTITION='internal/endpoints/awsrulesfn/partition.go' UNIT_TEST_TAGS= BUILD_TAGS=-tags "example,codegen,integration,ec2env,perftest" @@ -81,6 +84,13 @@ generate: smithy-generate update-requires gen-repo-mod-replace update-module-met gen-config-asserts gen-internal-codegen copy-attributevalue-feature gen-mod-dropreplace-smithy-. min-go-version-. \ tidy-modules-. add-module-license-files gen-aws-ptrs format +generate-tmpreplace-smithy: smithy-generate update-requires gen-repo-mod-replace update-module-metadata smithy-annotate-stable \ +gen-config-asserts gen-internal-codegen copy-attributevalue-feature gen-mod-replace-smithy-. min-go-version-. \ +tidy-modules-. add-module-license-files gen-aws-ptrs format gen-mod-dropreplace-smithy-. reset-sum + +reset-sum: + find . -name go.sum -exec git checkout -- {} \; + smithy-generate: cd codegen && ./gradlew clean build -Plog-tests && ./gradlew clean @@ -460,7 +470,9 @@ lint: @lint=`golint ./...`; \ dolint=`echo "$$lint" | grep -E -v \ -e ${LINT_IGNORE_S3MANAGER_INPUT} \ - -e ${LINTIGNORESINGLEFIGHT}`; \ + -e ${LINTIGNORESINGLEFIGHT} \ + -e ${LINT_IGNORE_AWSRULESFN_ARN} \ + -e ${LINT_IGNORE_AWSRULESFN_PARTITION}`; \ echo "$$dolint"; \ if [ "$$dolint" != "" ]; then exit 1; fi 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 index 20153586b..fe7aacbfa 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go @@ -68,6 +68,12 @@ type Config struct { // // 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 @@ -132,6 +138,14 @@ type Config struct { // `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 } // NewConfig returns a new Config pointer that can be chained with builder 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 index abee83b73..cd38b9280 100644 --- 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 @@ -3,4 +3,4 @@ package aws // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.18.1" +const goModuleVersion = "1.21.2" 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 index e6e87ac77..2de15528c 100644 --- 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 @@ -2,6 +2,7 @@ package middleware import ( "context" + "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/smithy-go/middleware" @@ -42,12 +43,13 @@ func (s RegisterServiceMetadata) HandleInitialize( // service metadata keys for storing and lookup of runtime stack information. type ( - serviceIDKey struct{} - signingNameKey struct{} - signingRegionKey struct{} - regionKey struct{} - operationNameKey struct{} - partitionIDKey struct{} + serviceIDKey struct{} + signingNameKey struct{} + signingRegionKey struct{} + regionKey struct{} + operationNameKey struct{} + partitionIDKey struct{} + requiresLegacyEndpointsKey struct{} ) // GetServiceID retrieves the service id from the context. @@ -104,6 +106,25 @@ func GetPartitionID(ctx context.Context) 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 signing name on the context. // // Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues 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 index 285b2bba8..af3447ddc 100644 --- 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 @@ -59,6 +59,11 @@ func (k SDKAgentKeyType) string() string { 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, +} + // requestUserAgent is a build middleware that set the User-Agent for the request. type requestUserAgent struct { sdkAgent, userAgent *smithyhttp.UserAgentBuilder @@ -178,24 +183,24 @@ func getOrAddRequestUserAgent(stack *middleware.Stack) (*requestUserAgent, error // AddUserAgentKey adds the component identified by name to the User-Agent string. func (u *requestUserAgent) AddUserAgentKey(key string) { - u.userAgent.AddKey(key) + 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(key, value) + u.userAgent.AddKeyValue(strings.Map(rules, key), strings.Map(rules, value)) } // AddUserAgentKey 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() + "/" + key) + u.userAgent.AddKey(keyType.string() + "/" + strings.Map(rules, key)) } // AddUserAgentKeyValue 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()+"/"+key, value) + u.userAgent.AddKeyValue(keyType.string(), strings.Map(rules, key)+"#"+strings.Map(rules, value)) } // ID the name of the middleware. @@ -241,3 +246,16 @@ func updateHTTPHeader(request *smithyhttp.Request, header string, value string) } 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 '-' + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/CHANGELOG.md index 402849cda..44d08cee7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/CHANGELOG.md @@ -1,3 +1,23 @@ +# v1.4.13 (2023-08-18) + +* No change notes available for this release. + +# v1.4.12 (2023-08-07) + +* No change notes available for this release. + +# v1.4.11 (2023-07-31) + +* No change notes available for this release. + +# v1.4.10 (2022-12-02) + +* No change notes available for this release. + +# v1.4.9 (2022-10-24) + +* No change notes available for this release. + # v1.4.8 (2022-09-14) * No change notes available for this release. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/go_module_metadata.go index 048add0bb..19f7e20cb 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/go_module_metadata.go @@ -3,4 +3,4 @@ package eventstream // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.4.8" +const goModuleVersion = "1.4.13" 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 index 6a99d4ea8..455b92515 100644 --- 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 @@ -41,6 +41,12 @@ 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. @@ -54,3 +60,10 @@ func (o *Object) key(name string, flatValue bool) Value { } return newValue(o.values, name, flatValue) } + +func (o *Object) keyWithValues(name string, flatValue bool) Value { + if o.prefix != "" { + return newAppendValue(o.values, fmt.Sprintf("%s.%s", o.prefix, 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 index 302525ab1..a9251521f 100644 --- 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 @@ -27,6 +27,15 @@ func newValue(values url.Values, key string, flat bool) Value { } } +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, 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 index 00d7d3eee..987affdde 100644 --- 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 @@ -97,11 +97,21 @@ func (r RetryableConnectionError) IsErrorRetryable(err error) aws.Ternary { var netOpErr *net.OpError var dnsError *net.DNSError - switch { - case errors.As(err, &dnsError): + if errors.As(err, &dnsError) { // NXDOMAIN errors should not be retried - retryable = !dnsError.IsNotFound && dnsError.IsTemporary + 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 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 index 64c4c4845..71b1a3521 100644 --- 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 @@ -48,6 +48,7 @@ var RequiredSignedHeaders = Rules{ "X-Amz-Request-Payer": 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{}{}, 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 index 749bda69e..0fb9b24e4 100644 --- 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 @@ -12,6 +12,7 @@ import ( "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" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -301,11 +302,23 @@ func (s *SignHTTPRequestMiddleware) HandleFinalize(ctx context.Context, in middl return out, metadata, &SigningError{Err: fmt.Errorf("failed to retrieve credentials: %w", err)} } - err = s.signer.SignHTTP(ctx, credentials, req.Request, payloadHash, signingName, signingRegion, sdk.NowTime(), + 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)} } 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 index afd069c1f..4d162556b 100644 --- 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 @@ -335,7 +335,7 @@ func (s Signer) SignHTTP(ctx context.Context, credentials aws.Credentials, r *ht // // expires := 20 * time.Minute // query := req.URL.Query() -// query.Set("X-Amz-Expires", strconv.FormatInt(int64(expires/time.Second), 10) +// 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. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/ci-find-smithy-go.sh b/vendor/github.com/aws/aws-sdk-go-v2/ci-find-smithy-go.sh new file mode 100644 index 000000000..4da5d09cb --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/ci-find-smithy-go.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +# looks for (and modreplaces if existing) a smithy-go branch matching the +# current branch name +# +# the loop will unfurl -*s off of the branch, e.g. sdk branch +# 'feat-foo-bar-baz' will match any of the following (in order): +# - feat-foo-bar-baz +# - feat-foo-bar +# - feat-foo + +if [ -z "$SMITHY_GO_REPOSITORY" ]; then + SMITHY_GO_REPOSITORY=aws/smithy-go +fi + +if [ -z "$RUNNER_TMPDIR" ]; then + echo env RUNNER_TMPDIR is required + exit 1 +fi + +branch=$(git branch --show-current) +if [ "$branch" == main ]; then + echo aws-sdk-go-v2 is on branch main, stop + exit 0 +fi + +# For PR workflows, only the triggering ref is checked out, which in isolation +# is not recognized as a branch by git. Use the specific workflow env instead. +if [ -z "$branch" ]; then + branch=$GITHUB_HEAD_REF +fi + +if [ -n "$GIT_PAT" ]; then + repository=https://$GIT_PAT@github.com/$SMITHY_GO_REPOSITORY +else + repository=https://github.com/$SMITHY_GO_REPOSITORY +fi + +echo on branch \"$branch\" +while [ -n "$branch" ] && [[ "$branch" == *-* ]]; do + echo looking for "$branch"... + git ls-remote --exit-code --heads "$repository" refs/heads/"$branch" + if [ "$?" == 0 ]; then + echo found "$branch" + matched_branch=$branch + break + fi + + branch=${branch%-*} +done + +if [ -z "$matched_branch" ]; then + echo found no matching smithy-go branch, stop + exit 0 +fi + +git clone -b "$matched_branch" "$repository" "$RUNNER_TMPDIR"/smithy-go +SMITHY_GO_SRC=$RUNNER_TMPDIR/smithy-go make gen-mod-replace-smithy-. 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 index 325779c09..a1ecda86f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/CHANGELOG.md @@ -1,3 +1,86 @@ +# 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 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 index 5940f8e7e..bf26eab9a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/config.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/config.go @@ -2,18 +2,11 @@ package config import ( "context" + "os" "github.com/aws/aws-sdk-go-v2/aws" ) -// defaultLoaders are a slice of functions that will read external configuration -// sources for configuration values. These values are read by the AWSConfigResolvers -// using interfaces to extract specific information from the external configuration. -var defaultLoaders = []loader{ - loadEnvConfig, - loadSharedConfigIgnoreNotExist, -} - // defaultAWSConfigResolvers are a slice of functions that will resolve external // configuration values into AWS configuration values. // @@ -76,6 +69,9 @@ var defaultAWSConfigResolvers = []awsConfigResolver{ // Sets the resolved bearer authentication token API clients will use for // httpBearerAuth authentication scheme. resolveBearerAuthToken, + + // Sets the sdk app ID if present in shared config profile + resolveAppID, } // A Config represents a generic configuration value or set of values. This type @@ -187,7 +183,7 @@ func LoadDefaultConfig(ctx context.Context, optFns ...func(*LoadOptions) error) // assign Load Options to configs var cfgCpy = configs{options} - cfgCpy, err = cfgCpy.AppendFromLoaders(ctx, defaultLoaders) + cfgCpy, err = cfgCpy.AppendFromLoaders(ctx, resolveConfigLoaders(&options)) if err != nil { return aws.Config{}, err } @@ -199,3 +195,17 @@ func LoadDefaultConfig(ctx context.Context, optFns ...func(*LoadOptions) error) 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(awsProfileEnvVar) != "" || options.SharedConfigProfile != "" { + loaders[1] = loadSharedConfig + } else { + loaders[1] = loadSharedConfigIgnoreNotExist + } + + return loaders +} 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 index 18c8e0121..a142a45c5 100644 --- 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 @@ -69,6 +69,7 @@ const ( awsRetryMaxAttempts = "AWS_MAX_ATTEMPTS" awsRetryMode = "AWS_RETRY_MODE" + awsSdkAppID = "AWS_SDK_UA_APP_ID" ) var ( @@ -248,6 +249,9 @@ type EnvConfig struct { // // aws_retry_mode=standard RetryMode aws.RetryMode + + // aws sdk app ID that can be added to user agent header string + AppID string } // loadEnvConfig reads configuration values from the OS's environment variables. @@ -288,6 +292,8 @@ func NewEnvConfig() (EnvConfig, error) { cfg.RoleARN = os.Getenv(awsRoleARNEnvVar) cfg.RoleSessionName = os.Getenv(awsRoleSessionNameEnvVar) + cfg.AppID = os.Getenv(awsSdkAppID) + if err := setEndpointDiscoveryTypeFromEnvVal(&cfg.EnableEndpointDiscovery, []string{awsEnableEndpointDiscoveryEnvVar}); err != nil { return cfg, err } @@ -335,6 +341,10 @@ func (c EnvConfig) getDefaultsMode(ctx context.Context) (aws.DefaultsMode, bool, return c.DefaultsMode, true, nil } +func (c EnvConfig) getAppID(context.Context) (string, bool, error) { + return c.AppID, len(c.AppID) > 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) { @@ -482,9 +492,9 @@ func (c EnvConfig) GetS3UseARNRegion(ctx context.Context) (value, ok bool, err e return *c.S3UseARNRegion, true, nil } -// GetS3DisableMultRegionAccessPoints returns whether to disable multi-region access point +// GetS3DisableMultiRegionAccessPoints returns whether to disable multi-region access point // support for the S3 client. -func (c EnvConfig) GetS3DisableMultRegionAccessPoints(ctx context.Context) (value, ok bool, err error) { +func (c EnvConfig) GetS3DisableMultiRegionAccessPoints(ctx context.Context) (value, ok bool, err error) { if c.S3DisableMultiRegionAccessPoints == nil { return false, false, nil } 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 index 9c6d17216..887131d08 100644 --- 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 @@ -3,4 +3,4 @@ package config // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.18.27" +const goModuleVersion = "1.19.1" 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 index 625147e97..7480bb45e 100644 --- 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 @@ -172,6 +172,10 @@ type LoadOptions struct { // 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 @@ -199,6 +203,9 @@ type LoadOptions struct { // 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 } func (o LoadOptions) getDefaultsMode(ctx context.Context) (aws.DefaultsMode, bool, error) { @@ -241,6 +248,11 @@ func (o LoadOptions) getRegion(ctx context.Context) (string, bool, error) { 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 +} + // 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. @@ -253,6 +265,15 @@ func WithRegion(v string) LoadOptionsFunc { } } +// 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 + } +} + // getDefaultRegion returns DefaultRegion from config's LoadOptions func (o LoadOptions) getDefaultRegion(ctx context.Context) (string, bool, error) { if len(o.DefaultRegion) == 0 { @@ -859,6 +880,26 @@ func WithS3UseARNRegion(v bool) LoadOptionsFunc { } } +// 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 { 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 index 6f1ab8cd1..b05623515 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/provider.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/provider.go @@ -122,6 +122,43 @@ func getRegion(ctx context.Context, configs configs) (value string, found bool, 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 []Config) (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 +} + +// 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 +} + // ec2IMDSRegionProvider provides access to the ec2 imds region // configuration value type ec2IMDSRegionProvider interface { 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 index 4428ba49c..1187e8c48 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/resolve.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/resolve.go @@ -106,6 +106,17 @@ func resolveRegion(ctx context.Context, cfg *aws.Config, configs configs) error 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 +} + // 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 { 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 index aac8f8369..ae5ba7658 100644 --- 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 @@ -95,6 +95,8 @@ const ( retryModeKey = "retry_mode" caBundleKey = "ca_bundle" + + sdkAppID = "sdk_ua_app_id" ) // defaultSharedConfigProfile allows for swapping the default profile for testing @@ -267,6 +269,9 @@ type SharedConfig struct { // // ca_bundle=$HOME/my_custom_ca_bundle CustomCABundle string + + // aws sdk app ID that can be added to user agent header string + AppID string } func (c SharedConfig) getDefaultsMode(ctx context.Context) (value aws.DefaultsMode, ok bool, err error) { @@ -389,6 +394,11 @@ func (c SharedConfig) getCustomCABundle(context.Context) (io.Reader, bool, error 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 +} + // 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. @@ -730,6 +740,8 @@ func mergeSections(dst *ini.Sections, src ini.Sections) error { defaultsModeKey, retryModeKey, caBundleKey, + roleDurationSecondsKey, + retryMaxAttemptsKey, ssoSessionNameKey, ssoAccountIDKey, @@ -743,16 +755,6 @@ func mergeSections(dst *ini.Sections, src ini.Sections) error { } } - intKeys := []string{ - roleDurationSecondsKey, - retryMaxAttemptsKey, - } - for i := range intKeys { - if err := mergeIntKey(&srcSection, &dstSection, sectionName, intKeys[i]); err != nil { - return err - } - } - // set srcSection on dst srcSection *dst = dst.SetSection(sectionName, dstSection) } @@ -779,26 +781,6 @@ func mergeStringKey(srcSection *ini.Section, dstSection *ini.Section, sectionNam return nil } -func mergeIntKey(srcSection *ini.Section, dstSection *ini.Section, sectionName, key string) error { - if srcSection.Has(key) { - srcValue := srcSection.Int(key) - v, err := ini.NewIntValue(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, v) - 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", @@ -952,9 +934,16 @@ func (c *SharedConfig) setFromIniSection(profile string, section ini.Section) er 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) { - d := time.Duration(section.Int(roleDurationSecondsKey)) * time.Second - c.RoleDurationSeconds = &d + 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) @@ -985,6 +974,9 @@ func (c *SharedConfig) setFromIniSection(profile string, section ini.Section) er updateString(&c.CustomCABundle, section, caBundleKey) + // user agent app ID added to request User-Agent header + updateString(&c.AppID, section, sdkAppID) + // Shared Credentials creds := aws.Credentials{ AccessKeyID: section.String(accessKeyIDKey), @@ -1301,12 +1293,13 @@ func updateInt(dst *int, section ini.Section, key string) error { if !section.Has(key) { return nil } - if vt, _ := section.ValueType(key); vt != ini.IntegerType { - return fmt.Errorf("invalid value %s=%s, expect integer", - key, section.String(key)) + v, ok := section.Int(key) + if !ok { + return fmt.Errorf("invalid value %s=%s, expect integer", key, section.String(key)) } - *dst = int(section.Int(key)) + + *dst = int(v) return nil } @@ -1316,7 +1309,10 @@ func updateBool(dst *bool, section ini.Section, key string) { if !section.Has(key) { return } - *dst = section.Bool(key) + + // 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, @@ -1325,8 +1321,11 @@ 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 = section.Bool(key) + **dst = v } // updateEndpointDiscoveryType will only update the dst with the value in the section, if @@ -1358,7 +1357,8 @@ func updateUseDualStackEndpoint(dst *aws.DualStackEndpointState, section ini.Sec return } - if section.Bool(key) { + // 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 @@ -1374,7 +1374,8 @@ func updateUseFIPSEndpoint(dst *aws.FIPSEndpointState, section ini.Section, key return } - if section.Bool(key) { + // 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 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 index 0b0958bdf..ed558d3b9 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/CHANGELOG.md @@ -1,3 +1,71 @@ +# 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 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 index 878dfaf6e..5cf1064a6 100644 --- 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 @@ -3,4 +3,4 @@ package credentials // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.13.26" +const goModuleVersion = "1.13.43" 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 index b4d50c424..5605f42d6 100644 --- 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 @@ -1,3 +1,39 @@ +# 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 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 index 6fab6e917..ab96ef614 100644 --- 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 @@ -3,4 +3,4 @@ package imds // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.13.4" +const goModuleVersion = "1.13.13" 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 new file mode 100644 index 000000000..ff229c048 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/scheme.go @@ -0,0 +1,186 @@ +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" + +// 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, + 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{}) + + switch authScheme["name"] { + case SigV4: + v4Scheme := AuthenticationSchemeV4{ + Name: SigV4, + 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/configsources/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md index 297f1e42c..efcbed2e7 100644 --- 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 @@ -1,3 +1,39 @@ +# 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 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 index 2948b3154..2eab5803b 100644 --- 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 @@ -3,4 +3,4 @@ package configsources // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.1.34" +const goModuleVersion = "1.1.43" 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 new file mode 100644 index 000000000..e6223dd3b --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/arn.go @@ -0,0 +1,94 @@ +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 new file mode 100644 index 000000000..d5a365853 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/doc.go @@ -0,0 +1,3 @@ +// 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 new file mode 100644 index 000000000..df72da97c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/generate.go @@ -0,0 +1,7 @@ +//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 new file mode 100644 index 000000000..637e5fc18 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/host.go @@ -0,0 +1,51 @@ +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 new file mode 100644 index 000000000..ba6032758 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partition.go @@ -0,0 +1,75 @@ +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"` +} + +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 new file mode 100644 index 000000000..7ea49d4ea --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.go @@ -0,0 +1,343 @@ +// 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 nil 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)\\-\\w+\\-\\d+$", + DefaultConfig: PartitionConfig{ + Name: "aws", + DnsSuffix: "amazonaws.com", + DualStackDnsSuffix: "api.aws", + SupportsFIPS: true, + SupportsDualStack: true, + }, + 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-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, + }, + "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, + }, + "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, + }, + "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, + }, + "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, + }, + 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-us-gov", + RegionRegex: "^us\\-gov\\-\\w+\\-\\d+$", + DefaultConfig: PartitionConfig{ + Name: "aws-us-gov", + DnsSuffix: "amazonaws.com", + DualStackDnsSuffix: "api.aws", + SupportsFIPS: true, + SupportsDualStack: true, + }, + 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, + }, + }, + }, + { + ID: "aws-iso", + RegionRegex: "^us\\-iso\\-\\w+\\-\\d+$", + DefaultConfig: PartitionConfig{ + Name: "aws-iso", + DnsSuffix: "c2s.ic.gov", + DualStackDnsSuffix: "c2s.ic.gov", + SupportsFIPS: true, + SupportsDualStack: false, + }, + 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: "sc2s.sgov.gov", + SupportsFIPS: true, + SupportsDualStack: false, + }, + 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, + }, + }, + }, +} 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 new file mode 100644 index 000000000..ab107ca55 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json @@ -0,0 +1,213 @@ +{ + "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)\\-\\w+\\-\\d+$", + "regions" : { + "af-south-1" : { + "description" : "Africa (Cape Town)" + }, + "ap-east-1" : { + "description" : "Asia Pacific (Hong Kong)" + }, + "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)" + }, + "aws-global" : { + "description" : "AWS Standard global region" + }, + "ca-central-1" : { + "description" : "Canada (Central)" + }, + "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)" + }, + "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 China global region" + }, + "cn-north-1" : { + "description" : "China (Beijing)" + }, + "cn-northwest-1" : { + "description" : "China (Ningxia)" + } + } + }, { + "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 GovCloud (US) global region" + }, + "us-gov-east-1" : { + "description" : "AWS GovCloud (US-East)" + }, + "us-gov-west-1" : { + "description" : "AWS GovCloud (US-West)" + } + } + }, { + "id" : "aws-iso", + "outputs" : { + "dnsSuffix" : "c2s.ic.gov", + "dualStackDnsSuffix" : "c2s.ic.gov", + "implicitGlobalRegion" : "us-iso-east-1", + "name" : "aws-iso", + "supportsDualStack" : false, + "supportsFIPS" : true + }, + "regionRegex" : "^us\\-iso\\-\\w+\\-\\d+$", + "regions" : { + "aws-iso-global" : { + "description" : "AWS ISO (US) 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" : "sc2s.sgov.gov", + "implicitGlobalRegion" : "us-isob-east-1", + "name" : "aws-iso-b", + "supportsDualStack" : false, + "supportsFIPS" : true + }, + "regionRegex" : "^us\\-isob\\-\\w+\\-\\d+$", + "regions" : { + "aws-iso-b-global" : { + "description" : "AWS ISOB (US) global region" + }, + "us-isob-east-1" : { + "description" : "US ISOB East (Ohio)" + } + } + }, { + "id" : "aws-iso-e", + "outputs" : { + "dnsSuffix" : "cloud.adc-e.uk", + "dualStackDnsSuffix" : "cloud.adc-e.uk", + "implicitGlobalRegion" : "eu-isoe-west-1", + "name" : "aws-iso-e", + "supportsDualStack" : false, + "supportsFIPS" : true + }, + "regionRegex" : "^eu\\-isoe\\-\\w+\\-\\d+$", + "regions" : { } + }, { + "id" : "aws-iso-f", + "outputs" : { + "dnsSuffix" : "csp.hci.ic.gov", + "dualStackDnsSuffix" : "csp.hci.ic.gov", + "implicitGlobalRegion" : "us-isof-south-1", + "name" : "aws-iso-f", + "supportsDualStack" : false, + "supportsFIPS" : true + }, + "regionRegex" : "^us\\-isof\\-\\w+\\-\\d+$", + "regions" : { } + } ], + "version" : "1.1" +} \ No newline at end of file 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 index 0ffc56c39..bd830abea 100644 --- 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 @@ -1,3 +1,39 @@ +# 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 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 index 0a8b6901f..085819076 100644 --- 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 @@ -3,4 +3,4 @@ package endpoints // goModuleVersion is the tagged release for this module -const goModuleVersion = "2.4.28" +const goModuleVersion = "2.4.37" 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 index 494c4dbaf..8aab66186 100644 --- 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 @@ -1,3 +1,44 @@ +# 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 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 index 479343626..f92dc23cc 100644 --- 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 @@ -3,4 +3,4 @@ package ini // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.3.35" +const goModuleVersion = "1.3.45" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/literal_tokens.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/literal_tokens.go index eca42d1b2..efcd2e6c7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/literal_tokens.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/literal_tokens.go @@ -12,34 +12,6 @@ var ( runesFalse = []rune("false") ) -var literalValues = [][]rune{ - runesTrue, - runesFalse, -} - -func isBoolValue(b []rune) bool { - for _, lv := range literalValues { - if isCaselessLitValue(lv, b) { - return true - } - } - return false -} - -func isLitValue(want, have []rune) bool { - if len(have) < len(want) { - return false - } - - for i := 0; i < len(want); i++ { - if want[i] != have[i] { - return false - } - } - - return true -} - // isCaselessLitValue is a caseless value comparison, assumes want is already lower-cased for efficiency. func isCaselessLitValue(want, have []rune) bool { if len(have) < len(want) { @@ -55,68 +27,6 @@ func isCaselessLitValue(want, have []rune) bool { return true } -// isNumberValue will return whether not the leading characters in -// a byte slice is a number. A number is delimited by whitespace or -// the newline token. -// -// A number is defined to be in a binary, octal, decimal (int | float), hex format, -// or in scientific notation. -func isNumberValue(b []rune) bool { - negativeIndex := 0 - helper := numberHelper{} - needDigit := false - - for i := 0; i < len(b); i++ { - negativeIndex++ - - switch b[i] { - case '-': - if helper.IsNegative() || negativeIndex != 1 { - return false - } - helper.Determine(b[i]) - needDigit = true - continue - case 'e', 'E': - if err := helper.Determine(b[i]); err != nil { - return false - } - negativeIndex = 0 - needDigit = true - continue - case 'b': - if helper.numberFormat == hex { - break - } - fallthrough - case 'o', 'x': - needDigit = true - if i == 0 { - return false - } - - fallthrough - case '.': - if err := helper.Determine(b[i]); err != nil { - return false - } - needDigit = true - continue - } - - if i > 0 && (isNewline(b[i:]) || isWhitespace(b[i])) { - return !needDigit - } - - if !helper.CorrectByte(b[i]) { - return false - } - needDigit = false - } - - return !needDigit -} - func isValid(b []rune) (bool, int, error) { if len(b) == 0 { // TODO: should probably return an error @@ -138,14 +48,8 @@ func (v ValueType) String() string { switch v { case NoneType: return "NONE" - case DecimalType: - return "FLOAT" - case IntegerType: - return "INT" case StringType: return "STRING" - case BoolType: - return "BOOL" } return "" @@ -154,11 +58,9 @@ func (v ValueType) String() string { // ValueType enums const ( NoneType = ValueType(iota) - DecimalType - IntegerType StringType QuotedStringType - BoolType + // FUTURE(2226) MapType ) // Value is a union container @@ -166,10 +68,8 @@ type Value struct { Type ValueType raw []rune - integer int64 - decimal float64 - boolean bool - str string + str string + // FUTURE(2226) mp map[string]string } func newValue(t ValueType, base int, raw []rune) (Value, error) { @@ -177,36 +77,15 @@ func newValue(t ValueType, base int, raw []rune) (Value, error) { Type: t, raw: raw, } - var err error switch t { - case DecimalType: - v.decimal, err = strconv.ParseFloat(string(raw), 64) - case IntegerType: - if base != 10 { - raw = raw[2:] - } - - v.integer, err = strconv.ParseInt(string(raw), base, 64) case StringType: v.str = string(raw) case QuotedStringType: v.str = string(raw[1 : len(raw)-1]) - case BoolType: - v.boolean = isCaselessLitValue(runesTrue, v.raw) - } - - // issue 2253 - // - // if the value trying to be parsed is too large, then we will use - // the 'StringType' and raw value instead. - if nerr, ok := err.(*strconv.NumError); ok && nerr.Err == strconv.ErrRange { - v.Type = StringType - v.str = string(raw) - err = nil } - return v, err + return v, nil } // NewStringValue returns a Value type generated using a string input. @@ -214,24 +93,12 @@ func NewStringValue(str string) (Value, error) { return newValue(StringType, 10, []rune(str)) } -// NewIntValue returns a Value type generated using an int64 input. -func NewIntValue(i int64) (Value, error) { - v := strconv.FormatInt(i, 10) - return newValue(IntegerType, 10, []rune(v)) -} - func (v Value) String() string { switch v.Type { - case DecimalType: - return fmt.Sprintf("decimal: %f", v.decimal) - case IntegerType: - return fmt.Sprintf("integer: %d", v.integer) case StringType: return fmt.Sprintf("string: %s", string(v.raw)) case QuotedStringType: return fmt.Sprintf("quoted string: %s", string(v.raw)) - case BoolType: - return fmt.Sprintf("bool: %t", v.boolean) default: return "union not set" } @@ -249,24 +116,6 @@ func newLitToken(b []rune) (Token, int, error) { } token = newToken(TokenLit, b[:n], QuotedStringType) - } else if isNumberValue(b) { - var base int - base, n, err = getNumericalValue(b) - if err != nil { - return token, 0, err - } - - value := b[:n] - vType := IntegerType - if contains(value, '.') || hasExponent(value) { - vType = DecimalType - } - token = newToken(TokenLit, value, vType) - token.base = base - } else if isBoolValue(b) { - n, err = getBoolValue(b) - - token = newToken(TokenLit, b[:n], BoolType) } else { n, err = getValue(b) token = newToken(TokenLit, b[:n], StringType) @@ -276,18 +125,33 @@ func newLitToken(b []rune) (Token, int, error) { } // IntValue returns an integer value -func (v Value) IntValue() int64 { - return v.integer +func (v Value) IntValue() (int64, bool) { + i, err := strconv.ParseInt(string(v.raw), 0, 64) + if err != nil { + return 0, false + } + return i, true } // FloatValue returns a float value -func (v Value) FloatValue() float64 { - return v.decimal +func (v Value) FloatValue() (float64, bool) { + f, err := strconv.ParseFloat(string(v.raw), 64) + if err != nil { + return 0, false + } + return f, true } // BoolValue returns a bool value -func (v Value) BoolValue() bool { - return v.boolean +func (v Value) BoolValue() (bool, bool) { + // we don't use ParseBool as it recognizes more than what we've + // historically supported + if isCaselessLitValue(runesTrue, v.raw) { + return true, true + } else if isCaselessLitValue(runesFalse, v.raw) { + return false, true + } + return false, false } func isTrimmable(r rune) bool { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/number_helper.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/number_helper.go deleted file mode 100644 index a45c0bc56..000000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/number_helper.go +++ /dev/null @@ -1,152 +0,0 @@ -package ini - -import ( - "bytes" - "fmt" - "strconv" -) - -const ( - none = numberFormat(iota) - binary - octal - decimal - hex - exponent -) - -type numberFormat int - -// numberHelper is used to dictate what format a number is in -// and what to do for negative values. Since -1e-4 is a valid -// number, we cannot just simply check for duplicate negatives. -type numberHelper struct { - numberFormat numberFormat - - negative bool - negativeExponent bool -} - -func (b numberHelper) Exists() bool { - return b.numberFormat != none -} - -func (b numberHelper) IsNegative() bool { - return b.negative || b.negativeExponent -} - -func (b *numberHelper) Determine(c rune) error { - if b.Exists() { - return NewParseError(fmt.Sprintf("multiple number formats: 0%v", string(c))) - } - - switch c { - case 'b': - b.numberFormat = binary - case 'o': - b.numberFormat = octal - case 'x': - b.numberFormat = hex - case 'e', 'E': - b.numberFormat = exponent - case '-': - if b.numberFormat != exponent { - b.negative = true - } else { - b.negativeExponent = true - } - case '.': - b.numberFormat = decimal - default: - return NewParseError(fmt.Sprintf("invalid number character: %v", string(c))) - } - - return nil -} - -func (b numberHelper) CorrectByte(c rune) bool { - switch { - case b.numberFormat == binary: - if !isBinaryByte(c) { - return false - } - case b.numberFormat == octal: - if !isOctalByte(c) { - return false - } - case b.numberFormat == hex: - if !isHexByte(c) { - return false - } - case b.numberFormat == decimal: - if !isDigit(c) { - return false - } - case b.numberFormat == exponent: - if !isDigit(c) { - return false - } - case b.negativeExponent: - if !isDigit(c) { - return false - } - case b.negative: - if !isDigit(c) { - return false - } - default: - if !isDigit(c) { - return false - } - } - - return true -} - -func (b numberHelper) Base() int { - switch b.numberFormat { - case binary: - return 2 - case octal: - return 8 - case hex: - return 16 - default: - return 10 - } -} - -func (b numberHelper) String() string { - buf := bytes.Buffer{} - i := 0 - - switch b.numberFormat { - case binary: - i++ - buf.WriteString(strconv.Itoa(i) + ": binary format\n") - case octal: - i++ - buf.WriteString(strconv.Itoa(i) + ": octal format\n") - case hex: - i++ - buf.WriteString(strconv.Itoa(i) + ": hex format\n") - case exponent: - i++ - buf.WriteString(strconv.Itoa(i) + ": exponent format\n") - default: - i++ - buf.WriteString(strconv.Itoa(i) + ": integer format\n") - } - - if b.negative { - i++ - buf.WriteString(strconv.Itoa(i) + ": negative format\n") - } - - if b.negativeExponent { - i++ - buf.WriteString(strconv.Itoa(i) + ": negative exponent format\n") - } - - return buf.String() -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/value_util.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/value_util.go index b5480fdeb..d38a9cd48 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/value_util.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/value_util.go @@ -41,149 +41,6 @@ func getStringValue(b []rune) (int, error) { return i + 1, nil } -// getBoolValue will return a boolean and the amount -// of bytes read -// -// an error will be returned if the boolean is not of a correct -// value -func getBoolValue(b []rune) (int, error) { - if len(b) < 4 { - return 0, NewParseError("invalid boolean value") - } - - n := 0 - for _, lv := range literalValues { - if len(lv) > len(b) { - continue - } - - if isCaselessLitValue(lv, b) { - n = len(lv) - } - } - - if n == 0 { - return 0, NewParseError("invalid boolean value") - } - - return n, nil -} - -// getNumericalValue will return a numerical string, the amount -// of bytes read, and the base of the number -// -// an error will be returned if the number is not of a correct -// value -func getNumericalValue(b []rune) (int, int, error) { - if !isDigit(b[0]) { - return 0, 0, NewParseError("invalid digit value") - } - - i := 0 - helper := numberHelper{} - -loop: - for negativeIndex := 0; i < len(b); i++ { - negativeIndex++ - - if !isDigit(b[i]) { - switch b[i] { - case '-': - if helper.IsNegative() || negativeIndex != 1 { - return 0, 0, NewParseError("parse error '-'") - } - - n := getNegativeNumber(b[i:]) - i += (n - 1) - helper.Determine(b[i]) - continue - case '.': - if err := helper.Determine(b[i]); err != nil { - return 0, 0, err - } - case 'e', 'E': - if err := helper.Determine(b[i]); err != nil { - return 0, 0, err - } - - negativeIndex = 0 - case 'b': - if helper.numberFormat == hex { - break - } - fallthrough - case 'o', 'x': - if i == 0 && b[i] != '0' { - return 0, 0, NewParseError("incorrect base format, expected leading '0'") - } - - if i != 1 { - return 0, 0, NewParseError(fmt.Sprintf("incorrect base format found %s at %d index", string(b[i]), i)) - } - - if err := helper.Determine(b[i]); err != nil { - return 0, 0, err - } - default: - if isWhitespace(b[i]) { - break loop - } - - if isNewline(b[i:]) { - break loop - } - - if !(helper.numberFormat == hex && isHexByte(b[i])) { - if i+2 < len(b) && !isNewline(b[i:i+2]) { - return 0, 0, NewParseError("invalid numerical character") - } else if !isNewline([]rune{b[i]}) { - return 0, 0, NewParseError("invalid numerical character") - } - - break loop - } - } - } - } - - return helper.Base(), i, nil -} - -// isDigit will return whether or not something is an integer -func isDigit(b rune) bool { - return b >= '0' && b <= '9' -} - -func hasExponent(v []rune) bool { - return contains(v, 'e') || contains(v, 'E') -} - -func isBinaryByte(b rune) bool { - switch b { - case '0', '1': - return true - default: - return false - } -} - -func isOctalByte(b rune) bool { - switch b { - case '0', '1', '2', '3', '4', '5', '6', '7': - return true - default: - return false - } -} - -func isHexByte(b rune) bool { - if isDigit(b) { - return true - } - return (b >= 'A' && b <= 'F') || - (b >= 'a' && b <= 'f') -} - func getValue(b []rune) (int, error) { i := 0 @@ -211,24 +68,6 @@ func getValue(b []rune) (int, error) { return i, nil } -// getNegativeNumber will return a negative number from a -// byte slice. This will iterate through all characters until -// a non-digit has been found. -func getNegativeNumber(b []rune) int { - if b[0] != '-' { - return 0 - } - - i := 1 - for ; i < len(b); i++ { - if !isDigit(b[i]) { - return i - } - } - - return i -} - // isEscaped will return whether or not the character is an escaped // character. func isEscaped(value []rune, b rune) bool { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/visitor.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/visitor.go index a07a63738..97fb3d7f3 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/visitor.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/visitor.go @@ -245,17 +245,17 @@ func (t Section) ValueType(k string) (ValueType, bool) { } // Bool returns a bool value at k -func (t Section) Bool(k string) bool { +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 { +func (t Section) Int(k string) (int64, bool) { return t.values[k].IntValue() } // Float64 returns a float value at k -func (t Section) Float64(k string) float64 { +func (t Section) Float64(k string) (float64, bool) { return t.values[k].FloatValue() } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/CHANGELOG.md index 2979f8b93..80510904e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/CHANGELOG.md @@ -1,3 +1,80 @@ +# v1.1.4 (2023-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.3 (2023-08-18) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.2 (2023-08-17) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.1 (2023-08-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.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.0.28 (2023-07-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.0.27 (2023-07-13) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.0.26 (2023-06-13) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.0.25 (2023-04-24) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.0.24 (2023-04-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.0.23 (2023-03-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.0.22 (2023-03-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.0.21 (2023-02-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.0.20 (2023-02-14) + +* No change notes available for this release. + +# v1.0.19 (2023-02-03) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.0.18 (2022-12-15) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.0.17 (2022-12-02) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.0.16 (2022-10-24) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.0.15 (2022-10-21) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.0.14 (2022-09-20) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/go_module_metadata.go index d4c420fbd..5a0e19ae6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/go_module_metadata.go @@ -3,4 +3,4 @@ package v4a // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.0.14" +const goModuleVersion = "1.1.4" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/middleware.go index 55d5e8abd..64b8b4e33 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/middleware.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/middleware.go @@ -3,13 +3,13 @@ package v4a import ( "context" "fmt" - "net/http" - "time" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" + "net/http" + "time" ) // HTTPSigner is SigV4a HTTP signer implementation @@ -71,10 +71,23 @@ func (s *SignHTTPRequestMiddleware) HandleFinalize( return out, metadata, &SigningError{Err: fmt.Errorf("failed to retrieve credentials: %w", err)} } - err = s.signer.SignHTTP(ctx, credentials, req.Request, payloadHash, signingName, []string{signingRegion}, time.Now().UTC(), func(o *SignerOptions) { - o.Logger = middleware.GetLogger(ctx) - o.LogSigning = s.logSigning - }) + 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, []string{signingRegion}, time.Now().UTC(), signerOptions...) if err != nil { return out, metadata, &SigningError{Err: fmt.Errorf("failed to sign http request, %w", err)} } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/modman.toml b/vendor/github.com/aws/aws-sdk-go-v2/modman.toml index b6d07cdd6..e505f5314 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/modman.toml +++ b/vendor/github.com/aws/aws-sdk-go-v2/modman.toml @@ -1,7 +1,7 @@ [dependencies] "github.com/aws/aws-sdk-go" = "v1.44.28" - "github.com/aws/smithy-go" = "v1.13.5" + "github.com/aws/smithy-go" = "v1.15.0" "github.com/google/go-cmp" = "v0.5.8" "github.com/jmespath/go-jmespath" = "v0.4.0" "golang.org/x/net" = "v0.1.0" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/CHANGELOG.md index c5699ec02..ac06c3635 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/CHANGELOG.md @@ -1,3 +1,72 @@ +# v1.20.2 (2023-10-12) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.20.1 (2023-10-06) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.20.0 (2023-09-11) + +* **Feature**: This release will have ValidationException be thrown from ECR LifecyclePolicy APIs in regions LifecyclePolicy is not supported, this includes existing Amazon Dedicated Cloud (ADC) regions. This release will also change Tag: TagValue and Tag: TagKey to required. + +# v1.19.5 (2023-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.4 (2023-08-18) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.3 (2023-08-17) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.2 (2023-08-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.1 (2023-08-01) + +* No change notes available for this release. + +# v1.19.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.18.15 (2023-07-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.14 (2023-07-13) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.13 (2023-06-15) + +* No change notes available for this release. + +# v1.18.12 (2023-06-13) + +* **Dependency Update**: Updated to the latest SDK module versions + +# 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 diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_client.go index c51da7830..f1984dd44 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_client.go @@ -4,6 +4,7 @@ package ecr import ( "context" + "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" @@ -46,8 +47,6 @@ func New(options Options, optFns ...func(*Options)) *Client { resolveHTTPSignerV4(&options) - resolveDefaultEndpointConfiguration(&options) - for _, fn := range optFns { fn(&options) } @@ -65,6 +64,14 @@ type Options struct { // 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 @@ -79,8 +86,18 @@ type Options struct { 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. This should be used over + // the deprecated EndpointResolver + EndpointResolverV2 EndpointResolverV2 + // Signature Version 4 (SigV4) Signer HTTPSignerV4 HTTPSignerV4 @@ -115,7 +132,7 @@ type Options struct { Retryer aws.Retryer // The RuntimeEnvironment configuration, only populated if the DefaultsMode is set - // to DefaultsModeAuto and is initialized using config.LoadDefaultConfig. You + // 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 @@ -139,14 +156,25 @@ func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { } } -// WithEndpointResolver returns a functional option for setting the Client's -// EndpointResolver option. +// 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 + } +} + type HTTPClient interface { Do(*http.Request) (*http.Response, error) } @@ -163,6 +191,8 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf ctx = middleware.ClearStackValues(ctx) stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) options := c.options.Copy() + resolveEndpointResolverV2(&options) + for _, fn := range optFns { fn(&options) } @@ -197,6 +227,30 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf 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 @@ -234,6 +288,7 @@ func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { APIOptions: cfg.APIOptions, Logger: cfg.Logger, ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) @@ -344,11 +399,19 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil { return } - o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions, NewDefaultEndpointResolver()) + o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) } -func addClientUserAgent(stack *middleware.Stack) error { - return awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "ecr", goModuleVersion)(stack) +func addClientUserAgent(stack *middleware.Stack, options Options) error { + if err := awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "ecr", goModuleVersion)(stack); err != nil { + return err + } + + if len(options.AppID) > 0 { + return awsmiddleware.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID)(stack) + } + + return nil } func addHTTPSignerV4Middleware(stack *middleware.Stack, o Options) error { @@ -432,3 +495,32 @@ func addRequestResponseLogging(stack *middleware.Stack, o Options) error { LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), }, middleware.After) } + +type endpointDisableHTTPSMiddleware struct { + EndpointDisableHTTPS bool +} + +func (*endpointDisableHTTPSMiddleware) ID() string { + return "endpointDisableHTTPSMiddleware" +} + +func (m *endpointDisableHTTPSMiddleware) 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) + } + + if m.EndpointDisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) { + req.URL.Scheme = "http" + } + + return next.HandleSerialize(ctx, in) + +} +func addendpointDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { + return stack.Serialize.Insert(&endpointDisableHTTPSMiddleware{ + EndpointDisableHTTPS: o.EndpointOptions.DisableHTTPS, + }, "OperationSerializer", middleware.Before) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchCheckLayerAvailability.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchCheckLayerAvailability.go index cea7521f6..8cc701c6f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchCheckLayerAvailability.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchCheckLayerAvailability.go @@ -4,9 +4,14 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -57,8 +62,8 @@ type BatchCheckLayerAvailabilityOutput struct { // Any failures associated with the call. Failures []types.LayerFailure - // A list of image layer objects corresponding to the image layer references in the - // request. + // A list of image layer objects corresponding to the image layer references in + // the request. Layers []types.Layer // Metadata pertaining to the operation's result. @@ -76,6 +81,9 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -103,7 +111,7 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -112,12 +120,18 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addBatchCheckLayerAvailabilityResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpBatchCheckLayerAvailabilityValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opBatchCheckLayerAvailability(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -127,6 +141,9 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -138,3 +155,126 @@ func newServiceMetadataMiddleware_opBatchCheckLayerAvailability(region string) * OperationName: "BatchCheckLayerAvailability", } } + +type opBatchCheckLayerAvailabilityResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opBatchCheckLayerAvailabilityResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opBatchCheckLayerAvailabilityResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addBatchCheckLayerAvailabilityResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opBatchCheckLayerAvailabilityResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchDeleteImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchDeleteImage.go index 80c9d5b5c..53816800d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchDeleteImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchDeleteImage.go @@ -4,15 +4,20 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Deletes a list of specified images within a repository. Images are specified -// with either an imageTag or imageDigest. You can remove a tag from an image by +// with either an imageTag or imageDigest . You can remove a tag from an image by // specifying the image's tag in your request. When you remove the last tag from an // image, the image is deleted from your repository. You can completely delete an // image (and all of its tags) by specifying the image's digest in your request. @@ -32,11 +37,11 @@ func (c *Client) BatchDeleteImage(ctx context.Context, params *BatchDeleteImageI } // Deletes specified images within a specified repository. Images are specified -// with either the imageTag or imageDigest. +// with either the imageTag or imageDigest . type BatchDeleteImageInput struct { - // A list of image ID references that correspond to images to delete. The format of - // the imageIds reference is imageTag=tag or imageDigest=digest. + // A list of image ID references that correspond to images to delete. The format + // of the imageIds reference is imageTag=tag or imageDigest=digest . // // This member is required. ImageIds []types.ImageIdentifier @@ -77,6 +82,9 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -104,7 +112,7 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -113,12 +121,18 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addBatchDeleteImageResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpBatchDeleteImageValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opBatchDeleteImage(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -128,6 +142,9 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -139,3 +156,126 @@ func newServiceMetadataMiddleware_opBatchDeleteImage(region string) *awsmiddlewa OperationName: "BatchDeleteImage", } } + +type opBatchDeleteImageResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opBatchDeleteImageResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opBatchDeleteImageResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addBatchDeleteImageResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opBatchDeleteImageResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetImage.go index b2724f89a..d2f2d85f8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetImage.go @@ -4,15 +4,20 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Gets detailed information for an image. Images are specified with either an -// imageTag or imageDigest. When an image is pulled, the BatchGetImage API is +// imageTag or imageDigest . When an image is pulled, the BatchGetImage API is // called once to retrieve the image manifest. func (c *Client) BatchGetImage(ctx context.Context, params *BatchGetImageInput, optFns ...func(*Options)) (*BatchGetImageOutput, error) { if params == nil { @@ -32,7 +37,7 @@ func (c *Client) BatchGetImage(ctx context.Context, params *BatchGetImageInput, type BatchGetImageInput struct { // A list of image ID references that correspond to images to describe. The format - // of the imageIds reference is imageTag=tag or imageDigest=digest. + // of the imageIds reference is imageTag=tag or imageDigest=digest . // // This member is required. ImageIds []types.ImageIdentifier @@ -79,6 +84,9 @@ func (c *Client) addOperationBatchGetImageMiddlewares(stack *middleware.Stack, o if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -106,7 +114,7 @@ func (c *Client) addOperationBatchGetImageMiddlewares(stack *middleware.Stack, o if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -115,12 +123,18 @@ func (c *Client) addOperationBatchGetImageMiddlewares(stack *middleware.Stack, o if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addBatchGetImageResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpBatchGetImageValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opBatchGetImage(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -130,6 +144,9 @@ func (c *Client) addOperationBatchGetImageMiddlewares(stack *middleware.Stack, o if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -141,3 +158,126 @@ func newServiceMetadataMiddleware_opBatchGetImage(region string) *awsmiddleware. OperationName: "BatchGetImage", } } + +type opBatchGetImageResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opBatchGetImageResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opBatchGetImageResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addBatchGetImageResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opBatchGetImageResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetRepositoryScanningConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetRepositoryScanningConfiguration.go index 42adcbbc4..30591dcdf 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetRepositoryScanningConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetRepositoryScanningConfiguration.go @@ -4,9 +4,14 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -60,6 +65,9 @@ func (c *Client) addOperationBatchGetRepositoryScanningConfigurationMiddlewares( if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -87,7 +95,7 @@ func (c *Client) addOperationBatchGetRepositoryScanningConfigurationMiddlewares( if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -96,12 +104,18 @@ func (c *Client) addOperationBatchGetRepositoryScanningConfigurationMiddlewares( if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addBatchGetRepositoryScanningConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpBatchGetRepositoryScanningConfigurationValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opBatchGetRepositoryScanningConfiguration(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -111,6 +125,9 @@ func (c *Client) addOperationBatchGetRepositoryScanningConfigurationMiddlewares( if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -122,3 +139,126 @@ func newServiceMetadataMiddleware_opBatchGetRepositoryScanningConfiguration(regi OperationName: "BatchGetRepositoryScanningConfiguration", } } + +type opBatchGetRepositoryScanningConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opBatchGetRepositoryScanningConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opBatchGetRepositoryScanningConfigurationResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addBatchGetRepositoryScanningConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opBatchGetRepositoryScanningConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CompleteLayerUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CompleteLayerUpload.go index ac1fe8a37..ee896d53e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CompleteLayerUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CompleteLayerUpload.go @@ -4,8 +4,13 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -87,6 +92,9 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -114,7 +122,7 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -123,12 +131,18 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addCompleteLayerUploadResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpCompleteLayerUploadValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCompleteLayerUpload(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -138,6 +152,9 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -149,3 +166,126 @@ func newServiceMetadataMiddleware_opCompleteLayerUpload(region string) *awsmiddl OperationName: "CompleteLayerUpload", } } + +type opCompleteLayerUploadResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opCompleteLayerUploadResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opCompleteLayerUploadResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addCompleteLayerUploadResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opCompleteLayerUploadResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreatePullThroughCacheRule.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreatePullThroughCacheRule.go index 6a67466e9..a31b8bb46 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreatePullThroughCacheRule.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreatePullThroughCacheRule.go @@ -4,8 +4,13 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "time" @@ -80,6 +85,9 @@ func (c *Client) addOperationCreatePullThroughCacheRuleMiddlewares(stack *middle if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -107,7 +115,7 @@ func (c *Client) addOperationCreatePullThroughCacheRuleMiddlewares(stack *middle if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -116,12 +124,18 @@ func (c *Client) addOperationCreatePullThroughCacheRuleMiddlewares(stack *middle if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addCreatePullThroughCacheRuleResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpCreatePullThroughCacheRuleValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreatePullThroughCacheRule(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -131,6 +145,9 @@ func (c *Client) addOperationCreatePullThroughCacheRuleMiddlewares(stack *middle if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -142,3 +159,126 @@ func newServiceMetadataMiddleware_opCreatePullThroughCacheRule(region string) *a OperationName: "CreatePullThroughCacheRule", } } + +type opCreatePullThroughCacheRuleResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opCreatePullThroughCacheRuleResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opCreatePullThroughCacheRuleResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addCreatePullThroughCacheRuleResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opCreatePullThroughCacheRuleResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepository.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepository.go index 1f22e5c82..1fdf9b212 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepository.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepository.go @@ -4,16 +4,20 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Creates a repository. For more information, see Amazon ECR repositories -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/Repositories.html) in -// the Amazon Elastic Container Registry User Guide. +// Creates a repository. For more information, see Amazon ECR repositories (https://docs.aws.amazon.com/AmazonECR/latest/userguide/Repositories.html) +// in the Amazon Elastic Container Registry User Guide. func (c *Client) CreateRepository(ctx context.Context, params *CreateRepositoryInput, optFns ...func(*Options)) (*CreateRepositoryOutput, error) { if params == nil { params = &CreateRepositoryInput{} @@ -32,8 +36,10 @@ func (c *Client) CreateRepository(ctx context.Context, params *CreateRepositoryI type CreateRepositoryInput struct { // The name to use for the repository. The repository name may be specified on its - // own (such as nginx-web-app) or it can be prepended with a namespace to group the - // repository into a category (such as project-a/nginx-web-app). + // own (such as nginx-web-app ) or it can be prepended with a namespace to group + // the repository into a category (such as project-a/nginx-web-app ). The + // repository name must start with a letter and can only contain lowercase letters, + // numbers, hyphens, underscores, and forward slashes. // // This member is required. RepositoryName *string @@ -47,8 +53,8 @@ type CreateRepositoryInput struct { // repository. ImageScanningConfiguration *types.ImageScanningConfiguration - // The tag mutability setting for the repository. If this parameter is omitted, the - // default setting of MUTABLE will be used which will allow image tags to be + // The tag mutability setting for the repository. If this parameter is omitted, + // the default setting of MUTABLE will be used which will allow image tags to be // overwritten. If IMMUTABLE is specified, all image tags within the repository // will be immutable which will prevent them from being overwritten. ImageTagMutability types.ImageTagMutability @@ -86,6 +92,9 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -113,7 +122,7 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -122,12 +131,18 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addCreateRepositoryResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpCreateRepositoryValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateRepository(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -137,6 +152,9 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -148,3 +166,126 @@ func newServiceMetadataMiddleware_opCreateRepository(region string) *awsmiddlewa OperationName: "CreateRepository", } } + +type opCreateRepositoryResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opCreateRepositoryResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opCreateRepositoryResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addCreateRepositoryResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opCreateRepositoryResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteLifecyclePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteLifecyclePolicy.go index 1f215085f..53c4d5327 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteLifecyclePolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteLifecyclePolicy.go @@ -4,8 +4,13 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "time" @@ -71,6 +76,9 @@ func (c *Client) addOperationDeleteLifecyclePolicyMiddlewares(stack *middleware. if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -98,7 +106,7 @@ func (c *Client) addOperationDeleteLifecyclePolicyMiddlewares(stack *middleware. if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -107,12 +115,18 @@ func (c *Client) addOperationDeleteLifecyclePolicyMiddlewares(stack *middleware. if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDeleteLifecyclePolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteLifecyclePolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteLifecyclePolicy(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -122,6 +136,9 @@ func (c *Client) addOperationDeleteLifecyclePolicyMiddlewares(stack *middleware. if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -133,3 +150,126 @@ func newServiceMetadataMiddleware_opDeleteLifecyclePolicy(region string) *awsmid OperationName: "DeleteLifecyclePolicy", } } + +type opDeleteLifecyclePolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteLifecyclePolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteLifecyclePolicyResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteLifecyclePolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteLifecyclePolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeletePullThroughCacheRule.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeletePullThroughCacheRule.go index 1f4bd9701..658c314c6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeletePullThroughCacheRule.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeletePullThroughCacheRule.go @@ -4,8 +4,13 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "time" @@ -72,6 +77,9 @@ func (c *Client) addOperationDeletePullThroughCacheRuleMiddlewares(stack *middle if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -99,7 +107,7 @@ func (c *Client) addOperationDeletePullThroughCacheRuleMiddlewares(stack *middle if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -108,12 +116,18 @@ func (c *Client) addOperationDeletePullThroughCacheRuleMiddlewares(stack *middle if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDeletePullThroughCacheRuleResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeletePullThroughCacheRuleValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeletePullThroughCacheRule(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -123,6 +137,9 @@ func (c *Client) addOperationDeletePullThroughCacheRuleMiddlewares(stack *middle if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -134,3 +151,126 @@ func newServiceMetadataMiddleware_opDeletePullThroughCacheRule(region string) *a OperationName: "DeletePullThroughCacheRule", } } + +type opDeletePullThroughCacheRuleResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeletePullThroughCacheRuleResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeletePullThroughCacheRuleResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeletePullThroughCacheRuleResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeletePullThroughCacheRuleResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRegistryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRegistryPolicy.go index a9230f956..2c1f88628 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRegistryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRegistryPolicy.go @@ -4,8 +4,13 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -53,6 +58,9 @@ func (c *Client) addOperationDeleteRegistryPolicyMiddlewares(stack *middleware.S if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -80,7 +88,7 @@ func (c *Client) addOperationDeleteRegistryPolicyMiddlewares(stack *middleware.S if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -89,9 +97,15 @@ func (c *Client) addOperationDeleteRegistryPolicyMiddlewares(stack *middleware.S if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDeleteRegistryPolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteRegistryPolicy(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -101,6 +115,9 @@ func (c *Client) addOperationDeleteRegistryPolicyMiddlewares(stack *middleware.S if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -112,3 +129,126 @@ func newServiceMetadataMiddleware_opDeleteRegistryPolicy(region string) *awsmidd OperationName: "DeleteRegistryPolicy", } } + +type opDeleteRegistryPolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteRegistryPolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteRegistryPolicyResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteRegistryPolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteRegistryPolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepository.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepository.go index 525834b91..622a861e1 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepository.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepository.go @@ -4,9 +4,14 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -66,6 +71,9 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -93,7 +101,7 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -102,12 +110,18 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDeleteRepositoryResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteRepositoryValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteRepository(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -117,6 +131,9 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -128,3 +145,126 @@ func newServiceMetadataMiddleware_opDeleteRepository(region string) *awsmiddlewa OperationName: "DeleteRepository", } } + +type opDeleteRepositoryResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteRepositoryResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteRepositoryResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteRepositoryResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteRepositoryResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryPolicy.go index dd23305f8..6b7fb0bcf 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryPolicy.go @@ -4,8 +4,13 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -68,6 +73,9 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -95,7 +103,7 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -104,12 +112,18 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDeleteRepositoryPolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteRepositoryPolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteRepositoryPolicy(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -119,6 +133,9 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -130,3 +147,126 @@ func newServiceMetadataMiddleware_opDeleteRepositoryPolicy(region string) *awsmi OperationName: "DeleteRepositoryPolicy", } } + +type opDeleteRepositoryPolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteRepositoryPolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteRepositoryPolicyResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteRepositoryPolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteRepositoryPolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageReplicationStatus.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageReplicationStatus.go index 0edd166a7..ba73c5f8c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageReplicationStatus.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageReplicationStatus.go @@ -4,9 +4,14 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -72,6 +77,9 @@ func (c *Client) addOperationDescribeImageReplicationStatusMiddlewares(stack *mi if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -99,7 +107,7 @@ func (c *Client) addOperationDescribeImageReplicationStatusMiddlewares(stack *mi if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -108,12 +116,18 @@ func (c *Client) addOperationDescribeImageReplicationStatusMiddlewares(stack *mi if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDescribeImageReplicationStatusResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDescribeImageReplicationStatusValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeImageReplicationStatus(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -123,6 +137,9 @@ func (c *Client) addOperationDescribeImageReplicationStatusMiddlewares(stack *mi if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -134,3 +151,126 @@ func newServiceMetadataMiddleware_opDescribeImageReplicationStatus(region string OperationName: "DescribeImageReplicationStatus", } } + +type opDescribeImageReplicationStatusResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDescribeImageReplicationStatusResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDescribeImageReplicationStatusResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDescribeImageReplicationStatusResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDescribeImageReplicationStatusResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageScanFindings.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageScanFindings.go index 5908d7ed0..63464be1c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageScanFindings.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageScanFindings.go @@ -4,10 +4,14 @@ package ecr import ( "context" + "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithytime "github.com/aws/smithy-go/time" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -45,11 +49,11 @@ type DescribeImageScanFindingsInput struct { RepositoryName *string // The maximum number of image scan results returned by DescribeImageScanFindings - // in paginated output. When this parameter is used, DescribeImageScanFindings only - // returns maxResults results in a single page along with a nextToken response - // element. The remaining results of the initial request can be seen by sending - // another DescribeImageScanFindings request with the returned nextToken value. - // This value can be between 1 and 1000. If this parameter is not used, then + // in paginated output. When this parameter is used, DescribeImageScanFindings + // only returns maxResults results in a single page along with a nextToken + // response element. The remaining results of the initial request can be seen by + // sending another DescribeImageScanFindings request with the returned nextToken + // value. This value can be between 1 and 1000. If this parameter is not used, then // DescribeImageScanFindings returns up to 100 results and a nextToken value, if // applicable. MaxResults *int32 @@ -81,7 +85,7 @@ type DescribeImageScanFindingsOutput struct { ImageScanStatus *types.ImageScanStatus // The nextToken value to include in a future DescribeImageScanFindings request. - // When the results of a DescribeImageScanFindings request exceed maxResults, this + // When the results of a DescribeImageScanFindings request exceed maxResults , this // value can be used to retrieve the next page of results. This value is null when // there are no more results to return. NextToken *string @@ -107,6 +111,9 @@ func (c *Client) addOperationDescribeImageScanFindingsMiddlewares(stack *middlew if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -134,7 +141,7 @@ func (c *Client) addOperationDescribeImageScanFindingsMiddlewares(stack *middlew if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -143,12 +150,18 @@ func (c *Client) addOperationDescribeImageScanFindingsMiddlewares(stack *middlew if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDescribeImageScanFindingsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDescribeImageScanFindingsValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeImageScanFindings(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -158,6 +171,9 @@ func (c *Client) addOperationDescribeImageScanFindingsMiddlewares(stack *middlew if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -173,11 +189,11 @@ var _ DescribeImageScanFindingsAPIClient = (*Client)(nil) // DescribeImageScanFindings type DescribeImageScanFindingsPaginatorOptions struct { // The maximum number of image scan results returned by DescribeImageScanFindings - // in paginated output. When this parameter is used, DescribeImageScanFindings only - // returns maxResults results in a single page along with a nextToken response - // element. The remaining results of the initial request can be seen by sending - // another DescribeImageScanFindings request with the returned nextToken value. - // This value can be between 1 and 1000. If this parameter is not used, then + // in paginated output. When this parameter is used, DescribeImageScanFindings + // only returns maxResults results in a single page along with a nextToken + // response element. The remaining results of the initial request can be seen by + // sending another DescribeImageScanFindings request with the returned nextToken + // value. This value can be between 1 and 1000. If this parameter is not used, then // DescribeImageScanFindings returns up to 100 results and a nextToken value, if // applicable. Limit int32 @@ -273,9 +289,9 @@ type ImageScanCompleteWaiterOptions struct { // MinDelay must resolve to a value lesser than or equal to the MaxDelay. MinDelay time.Duration - // MaxDelay is the maximum amount of time to delay between retries. If unset or set - // to zero, ImageScanCompleteWaiter will use default max delay of 120 seconds. Note - // that MaxDelay must resolve to value greater than or equal to the MinDelay. + // MaxDelay is the maximum amount of time to delay between retries. If unset or + // set to zero, ImageScanCompleteWaiter will use default max delay of 120 seconds. + // Note that MaxDelay must resolve to value greater than or equal to the MinDelay. MaxDelay time.Duration // LogWaitAttempts is used to enable logging for waiter retry attempts @@ -323,10 +339,10 @@ func (w *ImageScanCompleteWaiter) Wait(ctx context.Context, params *DescribeImag return err } -// WaitForOutput calls the waiter function for ImageScanComplete waiter and returns -// the output of the successful operation. The maxWaitDur is the maximum wait -// duration the waiter will wait. The maxWaitDur is required and must be greater -// than zero. +// WaitForOutput calls the waiter function for ImageScanComplete waiter and +// returns the output of the successful operation. The maxWaitDur is the maximum +// wait duration the waiter will wait. The maxWaitDur is required and must be +// greater than zero. func (w *ImageScanCompleteWaiter) WaitForOutput(ctx context.Context, params *DescribeImageScanFindingsInput, maxWaitDur time.Duration, optFns ...func(*ImageScanCompleteWaiterOptions)) (*DescribeImageScanFindingsOutput, error) { if maxWaitDur <= 0 { return nil, fmt.Errorf("maximum wait time for waiter must be greater than zero") @@ -445,3 +461,126 @@ func newServiceMetadataMiddleware_opDescribeImageScanFindings(region string) *aw OperationName: "DescribeImageScanFindings", } } + +type opDescribeImageScanFindingsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDescribeImageScanFindingsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDescribeImageScanFindingsResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDescribeImageScanFindingsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDescribeImageScanFindingsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImages.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImages.go index f4b654290..788c7665e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImages.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImages.go @@ -4,19 +4,23 @@ package ecr import ( "context" + "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Returns metadata about the images in a repository. Beginning with Docker version -// 1.9, the Docker client compresses image layers before pushing them to a V2 -// Docker registry. The output of the docker images command shows the uncompressed -// image size, so it may return a larger image size than the image sizes returned -// by DescribeImages. +// Returns metadata about the images in a repository. Beginning with Docker +// version 1.9, the Docker client compresses image layers before pushing them to a +// V2 Docker registry. The output of the docker images command shows the +// uncompressed image size, so it may return a larger image size than the image +// sizes returned by DescribeImages . func (c *Client) DescribeImages(ctx context.Context, params *DescribeImagesInput, optFns ...func(*Options)) (*DescribeImagesOutput, error) { if params == nil { params = &DescribeImagesInput{} @@ -45,21 +49,21 @@ type DescribeImagesInput struct { // The list of image IDs for the requested repository. ImageIds []types.ImageIdentifier - // The maximum number of repository results returned by DescribeImages in paginated - // output. When this parameter is used, DescribeImages only returns maxResults - // results in a single page along with a nextToken response element. The remaining - // results of the initial request can be seen by sending another DescribeImages - // request with the returned nextToken value. This value can be between 1 and 1000. - // If this parameter is not used, then DescribeImages returns up to 100 results and - // a nextToken value, if applicable. This option cannot be used when you specify - // images with imageIds. + // The maximum number of repository results returned by DescribeImages in + // paginated output. When this parameter is used, DescribeImages only returns + // maxResults results in a single page along with a nextToken response element. + // The remaining results of the initial request can be seen by sending another + // DescribeImages request with the returned nextToken value. This value can be + // between 1 and 1000. If this parameter is not used, then DescribeImages returns + // up to 100 results and a nextToken value, if applicable. This option cannot be + // used when you specify images with imageIds . MaxResults *int32 // The nextToken value returned from a previous paginated DescribeImages request // where maxResults was used and the results exceeded the value of that parameter. // Pagination continues from the end of the previous results that returned the // nextToken value. This value is null when there are no more results to return. - // This option cannot be used when you specify images with imageIds. + // This option cannot be used when you specify images with imageIds . NextToken *string // The Amazon Web Services account ID associated with the registry that contains @@ -76,8 +80,8 @@ type DescribeImagesOutput struct { ImageDetails []types.ImageDetail // The nextToken value to include in a future DescribeImages request. When the - // results of a DescribeImages request exceed maxResults, this value can be used to - // retrieve the next page of results. This value is null when there are no more + // results of a DescribeImages request exceed maxResults , this value can be used + // to retrieve the next page of results. This value is null when there are no more // results to return. NextToken *string @@ -96,6 +100,9 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -123,7 +130,7 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -132,12 +139,18 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDescribeImagesResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDescribeImagesValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeImages(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -147,6 +160,9 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -160,14 +176,14 @@ var _ DescribeImagesAPIClient = (*Client)(nil) // DescribeImagesPaginatorOptions is the paginator options for DescribeImages type DescribeImagesPaginatorOptions struct { - // The maximum number of repository results returned by DescribeImages in paginated - // output. When this parameter is used, DescribeImages only returns maxResults - // results in a single page along with a nextToken response element. The remaining - // results of the initial request can be seen by sending another DescribeImages - // request with the returned nextToken value. This value can be between 1 and 1000. - // If this parameter is not used, then DescribeImages returns up to 100 results and - // a nextToken value, if applicable. This option cannot be used when you specify - // images with imageIds. + // The maximum number of repository results returned by DescribeImages in + // paginated output. When this parameter is used, DescribeImages only returns + // maxResults results in a single page along with a nextToken response element. + // The remaining results of the initial request can be seen by sending another + // DescribeImages request with the returned nextToken value. This value can be + // between 1 and 1000. If this parameter is not used, then DescribeImages returns + // up to 100 results and a nextToken value, if applicable. This option cannot be + // used when you specify images with imageIds . Limit int32 // Set to true if pagination should stop if the service returns a pagination token @@ -255,3 +271,126 @@ func newServiceMetadataMiddleware_opDescribeImages(region string) *awsmiddleware OperationName: "DescribeImages", } } + +type opDescribeImagesResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDescribeImagesResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDescribeImagesResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDescribeImagesResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDescribeImagesResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribePullThroughCacheRules.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribePullThroughCacheRules.go index 2bfefbd7a..85d4842bd 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribePullThroughCacheRules.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribePullThroughCacheRules.go @@ -4,10 +4,14 @@ package ecr import ( "context" + "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -65,7 +69,7 @@ type DescribePullThroughCacheRulesOutput struct { // The nextToken value to include in a future DescribePullThroughCacheRulesRequest // request. When the results of a DescribePullThroughCacheRulesRequest request - // exceed maxResults, this value can be used to retrieve the next page of results. + // exceed maxResults , this value can be used to retrieve the next page of results. // This value is null when there are no more results to return. NextToken *string @@ -87,6 +91,9 @@ func (c *Client) addOperationDescribePullThroughCacheRulesMiddlewares(stack *mid if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -114,7 +121,7 @@ func (c *Client) addOperationDescribePullThroughCacheRulesMiddlewares(stack *mid if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -123,9 +130,15 @@ func (c *Client) addOperationDescribePullThroughCacheRulesMiddlewares(stack *mid if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDescribePullThroughCacheRulesResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribePullThroughCacheRules(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -135,6 +148,9 @@ func (c *Client) addOperationDescribePullThroughCacheRulesMiddlewares(stack *mid if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -247,3 +263,126 @@ func newServiceMetadataMiddleware_opDescribePullThroughCacheRules(region string) OperationName: "DescribePullThroughCacheRules", } } + +type opDescribePullThroughCacheRulesResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDescribePullThroughCacheRulesResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDescribePullThroughCacheRulesResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDescribePullThroughCacheRulesResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDescribePullThroughCacheRulesResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRegistry.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRegistry.go index 8d5f44222..e231a8f77 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRegistry.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRegistry.go @@ -4,9 +4,14 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -56,6 +61,9 @@ func (c *Client) addOperationDescribeRegistryMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -83,7 +91,7 @@ func (c *Client) addOperationDescribeRegistryMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -92,9 +100,15 @@ func (c *Client) addOperationDescribeRegistryMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDescribeRegistryResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeRegistry(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -104,6 +118,9 @@ func (c *Client) addOperationDescribeRegistryMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -115,3 +132,126 @@ func newServiceMetadataMiddleware_opDescribeRegistry(region string) *awsmiddlewa OperationName: "DescribeRegistry", } } + +type opDescribeRegistryResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDescribeRegistryResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDescribeRegistryResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDescribeRegistryResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDescribeRegistryResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositories.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositories.go index cef08268c..71fcebce6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositories.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositories.go @@ -4,10 +4,14 @@ package ecr import ( "context" + "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -31,13 +35,14 @@ func (c *Client) DescribeRepositories(ctx context.Context, params *DescribeRepos type DescribeRepositoriesInput struct { // The maximum number of repository results returned by DescribeRepositories in - // paginated output. When this parameter is used, DescribeRepositories only returns - // maxResults results in a single page along with a nextToken response element. The - // remaining results of the initial request can be seen by sending another - // DescribeRepositories request with the returned nextToken value. This value can - // be between 1 and 1000. If this parameter is not used, then DescribeRepositories - // returns up to 100 results and a nextToken value, if applicable. This option - // cannot be used when you specify repositories with repositoryNames. + // paginated output. When this parameter is used, DescribeRepositories only + // returns maxResults results in a single page along with a nextToken response + // element. The remaining results of the initial request can be seen by sending + // another DescribeRepositories request with the returned nextToken value. This + // value can be between 1 and 1000. If this parameter is not used, then + // DescribeRepositories returns up to 100 results and a nextToken value, if + // applicable. This option cannot be used when you specify repositories with + // repositoryNames . MaxResults *int32 // The nextToken value returned from a previous paginated DescribeRepositories @@ -45,7 +50,7 @@ type DescribeRepositoriesInput struct { // parameter. Pagination continues from the end of the previous results that // returned the nextToken value. This value is null when there are no more results // to return. This option cannot be used when you specify repositories with - // repositoryNames. This token should be treated as an opaque identifier that is + // repositoryNames . This token should be treated as an opaque identifier that is // only used to retrieve the next items in a list and not for other programmatic // purposes. NextToken *string @@ -65,7 +70,7 @@ type DescribeRepositoriesInput struct { type DescribeRepositoriesOutput struct { // The nextToken value to include in a future DescribeRepositories request. When - // the results of a DescribeRepositories request exceed maxResults, this value can + // the results of a DescribeRepositories request exceed maxResults , this value can // be used to retrieve the next page of results. This value is null when there are // no more results to return. NextToken *string @@ -88,6 +93,9 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -115,7 +123,7 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -124,9 +132,15 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDescribeRepositoriesResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeRepositories(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -136,6 +150,9 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -151,13 +168,14 @@ var _ DescribeRepositoriesAPIClient = (*Client)(nil) // DescribeRepositories type DescribeRepositoriesPaginatorOptions struct { // The maximum number of repository results returned by DescribeRepositories in - // paginated output. When this parameter is used, DescribeRepositories only returns - // maxResults results in a single page along with a nextToken response element. The - // remaining results of the initial request can be seen by sending another - // DescribeRepositories request with the returned nextToken value. This value can - // be between 1 and 1000. If this parameter is not used, then DescribeRepositories - // returns up to 100 results and a nextToken value, if applicable. This option - // cannot be used when you specify repositories with repositoryNames. + // paginated output. When this parameter is used, DescribeRepositories only + // returns maxResults results in a single page along with a nextToken response + // element. The remaining results of the initial request can be seen by sending + // another DescribeRepositories request with the returned nextToken value. This + // value can be between 1 and 1000. If this parameter is not used, then + // DescribeRepositories returns up to 100 results and a nextToken value, if + // applicable. This option cannot be used when you specify repositories with + // repositoryNames . Limit int32 // Set to true if pagination should stop if the service returns a pagination token @@ -245,3 +263,126 @@ func newServiceMetadataMiddleware_opDescribeRepositories(region string) *awsmidd OperationName: "DescribeRepositories", } } + +type opDescribeRepositoriesResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDescribeRepositoriesResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDescribeRepositoriesResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDescribeRepositoriesResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDescribeRepositoriesResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAuthorizationToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAuthorizationToken.go index 4d6dfbbd6..f630eef05 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAuthorizationToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAuthorizationToken.go @@ -4,9 +4,14 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -17,8 +22,7 @@ import ( // hours. The authorizationToken returned is a base64 encoded string that can be // decoded and used in a docker login command to authenticate to a registry. The // CLI offers an get-login-password command that simplifies the login process. For -// more information, see Registry authentication -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/Registries.html#registry_auth) +// more information, see Registry authentication (https://docs.aws.amazon.com/AmazonECR/latest/userguide/Registries.html#registry_auth) // in the Amazon Elastic Container Registry User Guide. func (c *Client) GetAuthorizationToken(ctx context.Context, params *GetAuthorizationTokenInput, optFns ...func(*Options)) (*GetAuthorizationTokenOutput, error) { if params == nil { @@ -71,6 +75,9 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -98,7 +105,7 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -107,9 +114,15 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetAuthorizationTokenResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetAuthorizationToken(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -119,6 +132,9 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -130,3 +146,126 @@ func newServiceMetadataMiddleware_opGetAuthorizationToken(region string) *awsmid OperationName: "GetAuthorizationToken", } } + +type opGetAuthorizationTokenResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetAuthorizationTokenResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetAuthorizationTokenResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetAuthorizationTokenResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetAuthorizationTokenResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetDownloadUrlForLayer.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetDownloadUrlForLayer.go index 82b584fe3..26bb7b9f5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetDownloadUrlForLayer.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetDownloadUrlForLayer.go @@ -4,17 +4,22 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Retrieves the pre-signed Amazon S3 download URL corresponding to an image layer. -// You can only get URLs for image layers that are referenced in an image. When an -// image is pulled, the GetDownloadUrlForLayer API is called once per image layer -// that is not already cached. This operation is used by the Amazon ECR proxy and -// is not generally used by customers for pulling and pushing images. In most +// Retrieves the pre-signed Amazon S3 download URL corresponding to an image +// layer. You can only get URLs for image layers that are referenced in an image. +// When an image is pulled, the GetDownloadUrlForLayer API is called once per image +// layer that is not already cached. This operation is used by the Amazon ECR proxy +// and is not generally used by customers for pulling and pushing images. In most // cases, you should use the docker CLI to pull, tag, and push images. func (c *Client) GetDownloadUrlForLayer(ctx context.Context, params *GetDownloadUrlForLayerInput, optFns ...func(*Options)) (*GetDownloadUrlForLayerOutput, error) { if params == nil { @@ -74,6 +79,9 @@ func (c *Client) addOperationGetDownloadUrlForLayerMiddlewares(stack *middleware if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -101,7 +109,7 @@ func (c *Client) addOperationGetDownloadUrlForLayerMiddlewares(stack *middleware if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -110,12 +118,18 @@ func (c *Client) addOperationGetDownloadUrlForLayerMiddlewares(stack *middleware if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetDownloadUrlForLayerResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetDownloadUrlForLayerValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetDownloadUrlForLayer(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -125,6 +139,9 @@ func (c *Client) addOperationGetDownloadUrlForLayerMiddlewares(stack *middleware if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -136,3 +153,126 @@ func newServiceMetadataMiddleware_opGetDownloadUrlForLayer(region string) *awsmi OperationName: "GetDownloadUrlForLayer", } } + +type opGetDownloadUrlForLayerResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetDownloadUrlForLayerResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetDownloadUrlForLayerResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetDownloadUrlForLayerResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetDownloadUrlForLayerResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicy.go index 76e8a061c..ee6b4b6f6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicy.go @@ -4,8 +4,13 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "time" @@ -71,6 +76,9 @@ func (c *Client) addOperationGetLifecyclePolicyMiddlewares(stack *middleware.Sta if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -98,7 +106,7 @@ func (c *Client) addOperationGetLifecyclePolicyMiddlewares(stack *middleware.Sta if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -107,12 +115,18 @@ func (c *Client) addOperationGetLifecyclePolicyMiddlewares(stack *middleware.Sta if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetLifecyclePolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetLifecyclePolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetLifecyclePolicy(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -122,6 +136,9 @@ func (c *Client) addOperationGetLifecyclePolicyMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -133,3 +150,126 @@ func newServiceMetadataMiddleware_opGetLifecyclePolicy(region string) *awsmiddle OperationName: "GetLifecyclePolicy", } } + +type opGetLifecyclePolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetLifecyclePolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetLifecyclePolicyResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetLifecyclePolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetLifecyclePolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicyPreview.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicyPreview.go index 5114fd1b0..5de6abc4f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicyPreview.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicyPreview.go @@ -4,10 +4,14 @@ package ecr import ( "context" + "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithytime "github.com/aws/smithy-go/time" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -50,13 +54,13 @@ type GetLifecyclePolicyPreviewInput struct { // The maximum number of repository results returned by // GetLifecyclePolicyPreviewRequest in
 paginated output. When this parameter is // used, GetLifecyclePolicyPreviewRequest only returns
 maxResults results in a - // single page along with a nextToken
 response element. The remaining results of + // single page along with a nextToken 
 response element. The remaining results of // the initial request can be seen by sending
 another - // GetLifecyclePolicyPreviewRequest request with the returned nextToken
 value. + // GetLifecyclePolicyPreviewRequest request with the returned nextToken 
 value. // This value can be between 1 and 1000. If this
 parameter is not used, then // GetLifecyclePolicyPreviewRequest returns up to
 100 results and a nextToken // value, if
 applicable. This option cannot be used when you specify images with - // imageIds. + // imageIds . MaxResults *int32 // The nextToken value returned from a previous paginated @@ -64,7 +68,7 @@ type GetLifecyclePolicyPreviewInput struct { // results exceeded the value of that parameter. Pagination continues from the end // of the
 previous results that returned the nextToken value. This value is
 null // when there are no more results to return. This option cannot be used when you - // specify images with imageIds. + // specify images with imageIds . NextToken *string // The Amazon Web Services account ID associated with the registry that contains @@ -81,7 +85,7 @@ type GetLifecyclePolicyPreviewOutput struct { LifecyclePolicyText *string // The nextToken value to include in a future GetLifecyclePolicyPreview request. - // When the results of a GetLifecyclePolicyPreview request exceed maxResults, this + // When the results of a GetLifecyclePolicyPreview request exceed maxResults , this // value can be used to retrieve the next page of results. This value is null when // there are no more results to return. NextToken *string @@ -116,6 +120,9 @@ func (c *Client) addOperationGetLifecyclePolicyPreviewMiddlewares(stack *middlew if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -143,7 +150,7 @@ func (c *Client) addOperationGetLifecyclePolicyPreviewMiddlewares(stack *middlew if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -152,12 +159,18 @@ func (c *Client) addOperationGetLifecyclePolicyPreviewMiddlewares(stack *middlew if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetLifecyclePolicyPreviewResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetLifecyclePolicyPreviewValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetLifecyclePolicyPreview(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -167,6 +180,9 @@ func (c *Client) addOperationGetLifecyclePolicyPreviewMiddlewares(stack *middlew if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -184,13 +200,13 @@ type GetLifecyclePolicyPreviewPaginatorOptions struct { // The maximum number of repository results returned by // GetLifecyclePolicyPreviewRequest in
 paginated output. When this parameter is // used, GetLifecyclePolicyPreviewRequest only returns
 maxResults results in a - // single page along with a nextToken
 response element. The remaining results of + // single page along with a nextToken 
 response element. The remaining results of // the initial request can be seen by sending
 another - // GetLifecyclePolicyPreviewRequest request with the returned nextToken
 value. + // GetLifecyclePolicyPreviewRequest request with the returned nextToken 
 value. // This value can be between 1 and 1000. If this
 parameter is not used, then // GetLifecyclePolicyPreviewRequest returns up to
 100 results and a nextToken // value, if
 applicable. This option cannot be used when you specify images with - // imageIds. + // imageIds . Limit int32 // Set to true if pagination should stop if the service returns a pagination token @@ -286,10 +302,10 @@ type LifecyclePolicyPreviewCompleteWaiterOptions struct { // MaxDelay. MinDelay time.Duration - // MaxDelay is the maximum amount of time to delay between retries. If unset or set - // to zero, LifecyclePolicyPreviewCompleteWaiter will use default max delay of 120 - // seconds. Note that MaxDelay must resolve to value greater than or equal to the - // MinDelay. + // MaxDelay is the maximum amount of time to delay between retries. If unset or + // set to zero, LifecyclePolicyPreviewCompleteWaiter will use default max delay of + // 120 seconds. Note that MaxDelay must resolve to value greater than or equal to + // the MinDelay. MaxDelay time.Duration // LogWaitAttempts is used to enable logging for waiter retry attempts @@ -461,3 +477,126 @@ func newServiceMetadataMiddleware_opGetLifecyclePolicyPreview(region string) *aw OperationName: "GetLifecyclePolicyPreview", } } + +type opGetLifecyclePolicyPreviewResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetLifecyclePolicyPreviewResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetLifecyclePolicyPreviewResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetLifecyclePolicyPreviewResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetLifecyclePolicyPreviewResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryPolicy.go index b9086f937..23c0a5788 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryPolicy.go @@ -4,8 +4,13 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -53,6 +58,9 @@ func (c *Client) addOperationGetRegistryPolicyMiddlewares(stack *middleware.Stac if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -80,7 +88,7 @@ func (c *Client) addOperationGetRegistryPolicyMiddlewares(stack *middleware.Stac if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -89,9 +97,15 @@ func (c *Client) addOperationGetRegistryPolicyMiddlewares(stack *middleware.Stac if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetRegistryPolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRegistryPolicy(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -101,6 +115,9 @@ func (c *Client) addOperationGetRegistryPolicyMiddlewares(stack *middleware.Stac if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -112,3 +129,126 @@ func newServiceMetadataMiddleware_opGetRegistryPolicy(region string) *awsmiddlew OperationName: "GetRegistryPolicy", } } + +type opGetRegistryPolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetRegistryPolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetRegistryPolicyResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetRegistryPolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetRegistryPolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryScanningConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryScanningConfiguration.go index 07f5e4dc3..822c88c09 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryScanningConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryScanningConfiguration.go @@ -4,9 +4,14 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -54,6 +59,9 @@ func (c *Client) addOperationGetRegistryScanningConfigurationMiddlewares(stack * if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -81,7 +89,7 @@ func (c *Client) addOperationGetRegistryScanningConfigurationMiddlewares(stack * if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -90,9 +98,15 @@ func (c *Client) addOperationGetRegistryScanningConfigurationMiddlewares(stack * if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetRegistryScanningConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRegistryScanningConfiguration(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -102,6 +116,9 @@ func (c *Client) addOperationGetRegistryScanningConfigurationMiddlewares(stack * if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -113,3 +130,126 @@ func newServiceMetadataMiddleware_opGetRegistryScanningConfiguration(region stri OperationName: "GetRegistryScanningConfiguration", } } + +type opGetRegistryScanningConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetRegistryScanningConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetRegistryScanningConfigurationResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetRegistryScanningConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetRegistryScanningConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRepositoryPolicy.go index 15a292ad6..f5c6bb624 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRepositoryPolicy.go @@ -4,8 +4,13 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -67,6 +72,9 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -94,7 +102,7 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -103,12 +111,18 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetRepositoryPolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetRepositoryPolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRepositoryPolicy(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -118,6 +132,9 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -129,3 +146,126 @@ func newServiceMetadataMiddleware_opGetRepositoryPolicy(region string) *awsmiddl OperationName: "GetRepositoryPolicy", } } + +type opGetRepositoryPolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetRepositoryPolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetRepositoryPolicyResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetRepositoryPolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetRepositoryPolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_InitiateLayerUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_InitiateLayerUpload.go index d700d833f..dba5e3cce 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_InitiateLayerUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_InitiateLayerUpload.go @@ -4,8 +4,13 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -71,6 +76,9 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -98,7 +106,7 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -107,12 +115,18 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addInitiateLayerUploadResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpInitiateLayerUploadValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opInitiateLayerUpload(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -122,6 +136,9 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -133,3 +150,126 @@ func newServiceMetadataMiddleware_opInitiateLayerUpload(region string) *awsmiddl OperationName: "InitiateLayerUpload", } } + +type opInitiateLayerUploadResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opInitiateLayerUploadResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opInitiateLayerUploadResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addInitiateLayerUploadResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opInitiateLayerUploadResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListImages.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListImages.go index b3d096d5b..785e83adc 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListImages.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListImages.go @@ -4,17 +4,21 @@ package ecr import ( "context" + "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Lists all the image IDs for the specified repository. You can filter images // based on whether or not they are tagged by using the tagStatus filter and -// specifying either TAGGED, UNTAGGED or ANY. For example, you can filter your +// specifying either TAGGED , UNTAGGED or ANY . For example, you can filter your // results to return only UNTAGGED images and then pipe that result to a // BatchDeleteImage operation to delete them. Or, you can filter your results to // return only TAGGED images to list all of the tags in your repository. @@ -74,7 +78,7 @@ type ListImagesOutput struct { ImageIds []types.ImageIdentifier // The nextToken value to include in a future ListImages request. When the results - // of a ListImages request exceed maxResults, this value can be used to retrieve + // of a ListImages request exceed maxResults , this value can be used to retrieve // the next page of results. This value is null when there are no more results to // return. NextToken *string @@ -94,6 +98,9 @@ func (c *Client) addOperationListImagesMiddlewares(stack *middleware.Stack, opti if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -121,7 +128,7 @@ func (c *Client) addOperationListImagesMiddlewares(stack *middleware.Stack, opti if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -130,12 +137,18 @@ func (c *Client) addOperationListImagesMiddlewares(stack *middleware.Stack, opti if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addListImagesResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpListImagesValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListImages(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -145,6 +158,9 @@ func (c *Client) addOperationListImagesMiddlewares(stack *middleware.Stack, opti if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -251,3 +267,126 @@ func newServiceMetadataMiddleware_opListImages(region string) *awsmiddleware.Reg OperationName: "ListImages", } } + +type opListImagesResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListImagesResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListImagesResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListImagesResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListImagesResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListTagsForResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListTagsForResource.go index 91a372fe5..80147049f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListTagsForResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListTagsForResource.go @@ -4,9 +4,14 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -58,6 +63,9 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -85,7 +93,7 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -94,12 +102,18 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addListTagsForResourceResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpListTagsForResourceValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListTagsForResource(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -109,6 +123,9 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -120,3 +137,126 @@ func newServiceMetadataMiddleware_opListTagsForResource(region string) *awsmiddl OperationName: "ListTagsForResource", } } + +type opListTagsForResourceResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListTagsForResourceResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListTagsForResourceResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListTagsForResourceResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListTagsForResourceResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImage.go index 631a9b408..104ac9d2e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImage.go @@ -4,19 +4,24 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Creates or updates the image manifest and tags associated with an image. When an -// image is pushed and all new image layers have been uploaded, the PutImage API is -// called once to create or update the image manifest and the tags associated with -// the image. This operation is used by the Amazon ECR proxy and is not generally -// used by customers for pulling and pushing images. In most cases, you should use -// the docker CLI to pull, tag, and push images. +// Creates or updates the image manifest and tags associated with an image. When +// an image is pushed and all new image layers have been uploaded, the PutImage API +// is called once to create or update the image manifest and the tags associated +// with the image. This operation is used by the Amazon ECR proxy and is not +// generally used by customers for pulling and pushing images. In most cases, you +// should use the docker CLI to pull, tag, and push images. func (c *Client) PutImage(ctx context.Context, params *PutImageInput, optFns ...func(*Options)) (*PutImageOutput, error) { if params == nil { params = &PutImageInput{} @@ -85,6 +90,9 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -112,7 +120,7 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -121,12 +129,18 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addPutImageResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutImageValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutImage(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -136,6 +150,9 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -147,3 +164,126 @@ func newServiceMetadataMiddleware_opPutImage(region string) *awsmiddleware.Regis OperationName: "PutImage", } } + +type opPutImageResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutImageResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutImageResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutImageResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutImageResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageScanningConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageScanningConfiguration.go index 74d8fe456..cd0dd68d7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageScanningConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageScanningConfiguration.go @@ -4,16 +4,21 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // The PutImageScanningConfiguration API is being deprecated, in favor of // specifying the image scanning configuration at the registry level. For more -// information, see PutRegistryScanningConfiguration. Updates the image scanning +// information, see PutRegistryScanningConfiguration . Updates the image scanning // configuration for the specified repository. func (c *Client) PutImageScanningConfiguration(ctx context.Context, params *PutImageScanningConfigurationInput, optFns ...func(*Options)) (*PutImageScanningConfigurationOutput, error) { if params == nil { @@ -79,6 +84,9 @@ func (c *Client) addOperationPutImageScanningConfigurationMiddlewares(stack *mid if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -106,7 +114,7 @@ func (c *Client) addOperationPutImageScanningConfigurationMiddlewares(stack *mid if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -115,12 +123,18 @@ func (c *Client) addOperationPutImageScanningConfigurationMiddlewares(stack *mid if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addPutImageScanningConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutImageScanningConfigurationValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutImageScanningConfiguration(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -130,6 +144,9 @@ func (c *Client) addOperationPutImageScanningConfigurationMiddlewares(stack *mid if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -141,3 +158,126 @@ func newServiceMetadataMiddleware_opPutImageScanningConfiguration(region string) OperationName: "PutImageScanningConfiguration", } } + +type opPutImageScanningConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutImageScanningConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutImageScanningConfigurationResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutImageScanningConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutImageScanningConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageTagMutability.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageTagMutability.go index 5e42488a1..4e0ed7e17 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageTagMutability.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageTagMutability.go @@ -4,16 +4,20 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Updates the image tag mutability settings for the specified repository. For more -// information, see Image tag mutability -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-tag-mutability.html) +// Updates the image tag mutability settings for the specified repository. For +// more information, see Image tag mutability (https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-tag-mutability.html) // in the Amazon Elastic Container Registry User Guide. func (c *Client) PutImageTagMutability(ctx context.Context, params *PutImageTagMutabilityInput, optFns ...func(*Options)) (*PutImageTagMutabilityOutput, error) { if params == nil { @@ -78,6 +82,9 @@ func (c *Client) addOperationPutImageTagMutabilityMiddlewares(stack *middleware. if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -105,7 +112,7 @@ func (c *Client) addOperationPutImageTagMutabilityMiddlewares(stack *middleware. if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -114,12 +121,18 @@ func (c *Client) addOperationPutImageTagMutabilityMiddlewares(stack *middleware. if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addPutImageTagMutabilityResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutImageTagMutabilityValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutImageTagMutability(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -129,6 +142,9 @@ func (c *Client) addOperationPutImageTagMutabilityMiddlewares(stack *middleware. if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -140,3 +156,126 @@ func newServiceMetadataMiddleware_opPutImageTagMutability(region string) *awsmid OperationName: "PutImageTagMutability", } } + +type opPutImageTagMutabilityResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutImageTagMutabilityResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutImageTagMutabilityResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutImageTagMutabilityResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutImageTagMutabilityResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutLifecyclePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutLifecyclePolicy.go index 782382eef..e1d71358d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutLifecyclePolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutLifecyclePolicy.go @@ -4,15 +4,20 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Creates or updates the lifecycle policy for the specified repository. For more -// information, see Lifecycle policy template -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html). +// information, see Lifecycle policy template (https://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html) +// . func (c *Client) PutLifecyclePolicy(ctx context.Context, params *PutLifecyclePolicyInput, optFns ...func(*Options)) (*PutLifecyclePolicyOutput, error) { if params == nil { params = &PutLifecyclePolicyInput{} @@ -74,6 +79,9 @@ func (c *Client) addOperationPutLifecyclePolicyMiddlewares(stack *middleware.Sta if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -101,7 +109,7 @@ func (c *Client) addOperationPutLifecyclePolicyMiddlewares(stack *middleware.Sta if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -110,12 +118,18 @@ func (c *Client) addOperationPutLifecyclePolicyMiddlewares(stack *middleware.Sta if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addPutLifecyclePolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutLifecyclePolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutLifecyclePolicy(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -125,6 +139,9 @@ func (c *Client) addOperationPutLifecyclePolicyMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -136,3 +153,126 @@ func newServiceMetadataMiddleware_opPutLifecyclePolicy(region string) *awsmiddle OperationName: "PutLifecyclePolicy", } } + +type opPutLifecyclePolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutLifecyclePolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutLifecyclePolicyResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutLifecyclePolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutLifecyclePolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryPolicy.go index b253e0e0f..bbbba9764 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryPolicy.go @@ -4,8 +4,13 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -13,8 +18,7 @@ import ( // Creates or updates the permissions policy for your registry. A registry policy // is used to specify permissions for another Amazon Web Services account and is // used when configuring cross-account replication. For more information, see -// Registry permissions -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/registry-permissions.html) +// Registry permissions (https://docs.aws.amazon.com/AmazonECR/latest/userguide/registry-permissions.html) // in the Amazon Elastic Container Registry User Guide. func (c *Client) PutRegistryPolicy(ctx context.Context, params *PutRegistryPolicyInput, optFns ...func(*Options)) (*PutRegistryPolicyOutput, error) { if params == nil { @@ -33,9 +37,8 @@ func (c *Client) PutRegistryPolicy(ctx context.Context, params *PutRegistryPolic type PutRegistryPolicyInput struct { - // The JSON policy text to apply to your registry. The policy text follows the same - // format as IAM policy text. For more information, see Registry permissions - // (https://docs.aws.amazon.com/AmazonECR/latest/userguide/registry-permissions.html) + // The JSON policy text to apply to your registry. The policy text follows the + // same format as IAM policy text. For more information, see Registry permissions (https://docs.aws.amazon.com/AmazonECR/latest/userguide/registry-permissions.html) // in the Amazon Elastic Container Registry User Guide. // // This member is required. @@ -67,6 +70,9 @@ func (c *Client) addOperationPutRegistryPolicyMiddlewares(stack *middleware.Stac if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -94,7 +100,7 @@ func (c *Client) addOperationPutRegistryPolicyMiddlewares(stack *middleware.Stac if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -103,12 +109,18 @@ func (c *Client) addOperationPutRegistryPolicyMiddlewares(stack *middleware.Stac if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addPutRegistryPolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutRegistryPolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutRegistryPolicy(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -118,6 +130,9 @@ func (c *Client) addOperationPutRegistryPolicyMiddlewares(stack *middleware.Stac if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -129,3 +144,126 @@ func newServiceMetadataMiddleware_opPutRegistryPolicy(region string) *awsmiddlew OperationName: "PutRegistryPolicy", } } + +type opPutRegistryPolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutRegistryPolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutRegistryPolicyResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutRegistryPolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutRegistryPolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryScanningConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryScanningConfiguration.go index fe20cf376..7261c89af 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryScanningConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryScanningConfiguration.go @@ -4,9 +4,14 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -29,13 +34,14 @@ func (c *Client) PutRegistryScanningConfiguration(ctx context.Context, params *P type PutRegistryScanningConfigurationInput struct { - // The scanning rules to use for the registry. A scanning rule is used to determine - // which repository filters are used and at what frequency scanning will occur. + // The scanning rules to use for the registry. A scanning rule is used to + // determine which repository filters are used and at what frequency scanning will + // occur. Rules []types.RegistryScanningRule // The scanning type to set for the registry. When a registry scanning - // configuration is not defined, by default the BASIC scan type is used. When basic - // scanning is used, you may specify filters to determine which individual + // configuration is not defined, by default the BASIC scan type is used. When + // basic scanning is used, you may specify filters to determine which individual // repositories, or all repositories, are scanned when new images are pushed to // those repositories. Alternatively, you can do manual scans of images with basic // scanning. When the ENHANCED scan type is set, Amazon Inspector provides @@ -67,6 +73,9 @@ func (c *Client) addOperationPutRegistryScanningConfigurationMiddlewares(stack * if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -94,7 +103,7 @@ func (c *Client) addOperationPutRegistryScanningConfigurationMiddlewares(stack * if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -103,12 +112,18 @@ func (c *Client) addOperationPutRegistryScanningConfigurationMiddlewares(stack * if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addPutRegistryScanningConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutRegistryScanningConfigurationValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutRegistryScanningConfiguration(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -118,6 +133,9 @@ func (c *Client) addOperationPutRegistryScanningConfigurationMiddlewares(stack * if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -129,3 +147,126 @@ func newServiceMetadataMiddleware_opPutRegistryScanningConfiguration(region stri OperationName: "PutRegistryScanningConfiguration", } } + +type opPutRegistryScanningConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutRegistryScanningConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutRegistryScanningConfigurationResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutRegistryScanningConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutRegistryScanningConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutReplicationConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutReplicationConfiguration.go index e8e84df6e..dc230e812 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutReplicationConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutReplicationConfiguration.go @@ -4,9 +4,14 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -16,12 +21,11 @@ import ( // DescribeRegistry API action. The first time the PutReplicationConfiguration API // is called, a service-linked IAM role is created in your account for the // replication process. For more information, see Using service-linked roles for -// Amazon ECR -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/using-service-linked-roles.html) +// Amazon ECR (https://docs.aws.amazon.com/AmazonECR/latest/userguide/using-service-linked-roles.html) // in the Amazon Elastic Container Registry User Guide. When configuring // cross-account replication, the destination account must grant the source account // permission to replicate. This permission is controlled using a registry -// permissions policy. For more information, see PutRegistryPolicy. +// permissions policy. For more information, see PutRegistryPolicy . func (c *Client) PutReplicationConfiguration(ctx context.Context, params *PutReplicationConfigurationInput, optFns ...func(*Options)) (*PutReplicationConfigurationOutput, error) { if params == nil { params = &PutReplicationConfigurationInput{} @@ -67,6 +71,9 @@ func (c *Client) addOperationPutReplicationConfigurationMiddlewares(stack *middl if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -94,7 +101,7 @@ func (c *Client) addOperationPutReplicationConfigurationMiddlewares(stack *middl if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -103,12 +110,18 @@ func (c *Client) addOperationPutReplicationConfigurationMiddlewares(stack *middl if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addPutReplicationConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutReplicationConfigurationValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutReplicationConfiguration(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -118,6 +131,9 @@ func (c *Client) addOperationPutReplicationConfigurationMiddlewares(stack *middl if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -129,3 +145,126 @@ func newServiceMetadataMiddleware_opPutReplicationConfiguration(region string) * OperationName: "PutReplicationConfiguration", } } + +type opPutReplicationConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutReplicationConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutReplicationConfigurationResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutReplicationConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutReplicationConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_SetRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_SetRepositoryPolicy.go index 1078970c7..209df6c2d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_SetRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_SetRepositoryPolicy.go @@ -4,15 +4,19 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Applies a repository policy to the specified repository to control access -// permissions. For more information, see Amazon ECR Repository policies -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html) +// permissions. For more information, see Amazon ECR Repository policies (https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html) // in the Amazon Elastic Container Registry User Guide. func (c *Client) SetRepositoryPolicy(ctx context.Context, params *SetRepositoryPolicyInput, optFns ...func(*Options)) (*SetRepositoryPolicyOutput, error) { if params == nil { @@ -32,8 +36,7 @@ func (c *Client) SetRepositoryPolicy(ctx context.Context, params *SetRepositoryP type SetRepositoryPolicyInput struct { // The JSON repository policy text to apply to the repository. For more - // information, see Amazon ECR repository policies - // (https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policy-examples.html) + // information, see Amazon ECR repository policies (https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policy-examples.html) // in the Amazon Elastic Container Registry User Guide. // // This member is required. @@ -44,8 +47,8 @@ type SetRepositoryPolicyInput struct { // This member is required. RepositoryName *string - // If the policy you are attempting to set on a repository policy would prevent you - // from setting another policy in the future, you must force the + // If the policy you are attempting to set on a repository policy would prevent + // you from setting another policy in the future, you must force the // SetRepositoryPolicy operation. This is intended to prevent accidental repository // lock outs. Force bool @@ -84,6 +87,9 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -111,7 +117,7 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -120,12 +126,18 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetRepositoryPolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpSetRepositoryPolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opSetRepositoryPolicy(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -135,6 +147,9 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -146,3 +161,126 @@ func newServiceMetadataMiddleware_opSetRepositoryPolicy(region string) *awsmiddl OperationName: "SetRepositoryPolicy", } } + +type opSetRepositoryPolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opSetRepositoryPolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opSetRepositoryPolicyResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addSetRepositoryPolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opSetRepositoryPolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartImageScan.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartImageScan.go index 8a9785f49..b1dc74c73 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartImageScan.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartImageScan.go @@ -4,18 +4,22 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Starts an image vulnerability scan. An image scan can only be started once per // 24 hours on an individual image. This limit includes if an image was scanned on -// initial push. For more information, see Image scanning -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html) in -// the Amazon Elastic Container Registry User Guide. +// initial push. For more information, see Image scanning (https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html) +// in the Amazon Elastic Container Registry User Guide. func (c *Client) StartImageScan(ctx context.Context, params *StartImageScanInput, optFns ...func(*Options)) (*StartImageScanOutput, error) { if params == nil { params = &StartImageScanInput{} @@ -80,6 +84,9 @@ func (c *Client) addOperationStartImageScanMiddlewares(stack *middleware.Stack, if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -107,7 +114,7 @@ func (c *Client) addOperationStartImageScanMiddlewares(stack *middleware.Stack, if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -116,12 +123,18 @@ func (c *Client) addOperationStartImageScanMiddlewares(stack *middleware.Stack, if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addStartImageScanResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpStartImageScanValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opStartImageScan(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -131,6 +144,9 @@ func (c *Client) addOperationStartImageScanMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -142,3 +158,126 @@ func newServiceMetadataMiddleware_opStartImageScan(region string) *awsmiddleware OperationName: "StartImageScan", } } + +type opStartImageScanResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opStartImageScanResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opStartImageScanResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addStartImageScanResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opStartImageScanResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartLifecyclePolicyPreview.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartLifecyclePolicyPreview.go index 1169ac443..753970eae 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartLifecyclePolicyPreview.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartLifecyclePolicyPreview.go @@ -4,15 +4,20 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Starts a preview of a lifecycle policy for the specified repository. This allows -// you to see the results before associating the lifecycle policy with the +// Starts a preview of a lifecycle policy for the specified repository. This +// allows you to see the results before associating the lifecycle policy with the // repository. func (c *Client) StartLifecyclePolicyPreview(ctx context.Context, params *StartLifecyclePolicyPreviewInput, optFns ...func(*Options)) (*StartLifecyclePolicyPreviewOutput, error) { if params == nil { @@ -77,6 +82,9 @@ func (c *Client) addOperationStartLifecyclePolicyPreviewMiddlewares(stack *middl if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -104,7 +112,7 @@ func (c *Client) addOperationStartLifecyclePolicyPreviewMiddlewares(stack *middl if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -113,12 +121,18 @@ func (c *Client) addOperationStartLifecyclePolicyPreviewMiddlewares(stack *middl if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addStartLifecyclePolicyPreviewResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpStartLifecyclePolicyPreviewValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opStartLifecyclePolicyPreview(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -128,6 +142,9 @@ func (c *Client) addOperationStartLifecyclePolicyPreviewMiddlewares(stack *middl if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -139,3 +156,126 @@ func newServiceMetadataMiddleware_opStartLifecyclePolicyPreview(region string) * OperationName: "StartLifecyclePolicyPreview", } } + +type opStartLifecyclePolicyPreviewResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opStartLifecyclePolicyPreviewResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opStartLifecyclePolicyPreviewResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addStartLifecyclePolicyPreviewResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opStartLifecyclePolicyPreviewResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_TagResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_TagResource.go index d283acf67..cee213268 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_TagResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_TagResource.go @@ -4,9 +4,14 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -62,6 +67,9 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -89,7 +97,7 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -98,12 +106,18 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addTagResourceResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpTagResourceValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opTagResource(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -113,6 +127,9 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -124,3 +141,126 @@ func newServiceMetadataMiddleware_opTagResource(region string) *awsmiddleware.Re OperationName: "TagResource", } } + +type opTagResourceResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opTagResourceResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opTagResourceResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addTagResourceResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opTagResourceResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UntagResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UntagResource.go index e42275bde..74f12ad40 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UntagResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UntagResource.go @@ -4,8 +4,13 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -58,6 +63,9 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -85,7 +93,7 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -94,12 +102,18 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addUntagResourceResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpUntagResourceValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUntagResource(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -109,6 +123,9 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -120,3 +137,126 @@ func newServiceMetadataMiddleware_opUntagResource(region string) *awsmiddleware. OperationName: "UntagResource", } } + +type opUntagResourceResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opUntagResourceResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opUntagResourceResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addUntagResourceResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opUntagResourceResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UploadLayerPart.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UploadLayerPart.go index 4acf7e5b0..feb56bf09 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UploadLayerPart.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UploadLayerPart.go @@ -4,8 +4,13 @@ package ecr import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -59,9 +64,9 @@ type UploadLayerPartInput struct { // This member is required. UploadId *string - // The Amazon Web Services account ID associated with the registry to which you are - // uploading layer parts. If you do not specify a registry, the default registry is - // assumed. + // The Amazon Web Services account ID associated with the registry to which you + // are uploading layer parts. If you do not specify a registry, the default + // registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -96,6 +101,9 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -123,7 +131,7 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -132,12 +140,18 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addUploadLayerPartResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpUploadLayerPartValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUploadLayerPart(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -147,6 +161,9 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -158,3 +175,126 @@ func newServiceMetadataMiddleware_opUploadLayerPart(region string) *awsmiddlewar OperationName: "UploadLayerPart", } } + +type opUploadLayerPartResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opUploadLayerPartResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opUploadLayerPartResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addUploadLayerPartResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opUploadLayerPartResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/deserializers.go index 79c79b7ab..7d849ef54 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/deserializers.go @@ -991,6 +991,9 @@ func awsAwsjson11_deserializeOpErrorDeleteLifecyclePolicy(response *smithyhttp.R case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("ValidationException", errorCode): + return awsAwsjson11_deserializeErrorValidationException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -2554,6 +2557,9 @@ func awsAwsjson11_deserializeOpErrorGetLifecyclePolicy(response *smithyhttp.Resp case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("ValidationException", errorCode): + return awsAwsjson11_deserializeErrorValidationException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -2674,6 +2680,9 @@ func awsAwsjson11_deserializeOpErrorGetLifecyclePolicyPreview(response *smithyht case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("ValidationException", errorCode): + return awsAwsjson11_deserializeErrorValidationException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -3877,6 +3886,9 @@ func awsAwsjson11_deserializeOpErrorPutLifecyclePolicy(response *smithyhttp.Resp case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("ValidationException", errorCode): + return awsAwsjson11_deserializeErrorValidationException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -4597,6 +4609,9 @@ func awsAwsjson11_deserializeOpErrorStartLifecyclePolicyPreview(response *smithy case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("ValidationException", errorCode): + return awsAwsjson11_deserializeErrorValidationException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/doc.go index 602df615b..cd150610d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/doc.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/doc.go @@ -3,14 +3,14 @@ // Package ecr provides the API client, operations, and parameter types for Amazon // EC2 Container Registry. // -// Amazon Elastic Container Registry Amazon Elastic Container Registry (Amazon ECR) -// is a managed container image registry service. Customers can use the familiar -// Docker CLI, or their preferred client, to push, pull, and manage images. Amazon -// ECR provides a secure, scalable, and reliable registry for your Docker or Open -// Container Initiative (OCI) images. Amazon ECR supports private repositories with -// resource-based permissions using IAM so that specific users or Amazon EC2 -// instances can access repositories and images. Amazon ECR has service endpoints -// in each supported Region. For more information, see Amazon ECR endpoints -// (https://docs.aws.amazon.com/general/latest/gr/ecr.html) in the Amazon Web -// Services General Reference. +// Amazon Elastic Container Registry Amazon Elastic Container Registry (Amazon +// ECR) is a managed container image registry service. Customers can use the +// familiar Docker CLI, or their preferred client, to push, pull, and manage +// images. Amazon ECR provides a secure, scalable, and reliable registry for your +// Docker or Open Container Initiative (OCI) images. Amazon ECR supports private +// repositories with resource-based permissions using IAM so that specific users or +// Amazon EC2 instances can access repositories and images. Amazon ECR has service +// endpoints in each supported Region. For more information, see Amazon ECR +// endpoints (https://docs.aws.amazon.com/general/latest/gr/ecr.html) in the Amazon +// Web Services General Reference. package ecr diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/endpoints.go index e255bc9d5..8d169bdb2 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/endpoints.go @@ -8,9 +8,13 @@ import ( "fmt" "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/endpoints/awsrulesfn" internalendpoints "github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" smithyhttp "github.com/aws/smithy-go/transport/http" + "net/http" "net/url" "strings" ) @@ -39,13 +43,6 @@ func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointRe return fn(region, options) } -func resolveDefaultEndpointConfiguration(o *Options) { - if o.EndpointResolver != nil { - return - } - o.EndpointResolver = NewDefaultEndpointResolver() -} - // 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 @@ -79,6 +76,10 @@ func (*ResolveEndpoint) ID() string { 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) @@ -94,6 +95,11 @@ func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.Ser 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) } @@ -129,27 +135,10 @@ func removeResolveEndpointMiddleware(stack *middleware.Stack) error { type wrappedEndpointResolver struct { awsResolver aws.EndpointResolverWithOptions - resolver EndpointResolver } func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - if w.awsResolver == nil { - goto fallback - } - endpoint, err = w.awsResolver.ResolveEndpoint(ServiceID, region, options) - if err == nil { - return endpoint, nil - } - - if nf := (&aws.EndpointNotFoundError{}); !errors.As(err, &nf) { - return endpoint, err - } - -fallback: - if w.resolver == nil { - return endpoint, fmt.Errorf("default endpoint resolver provided was nil") - } - return w.resolver.ResolveEndpoint(region, options) + return w.awsResolver.ResolveEndpoint(ServiceID, region, options) } type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error) @@ -160,12 +149,13 @@ func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, opti var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil) -// withEndpointResolver returns an EndpointResolver that first delegates endpoint resolution to the awsResolver. -// If awsResolver returns aws.EndpointNotFoundError error, the resolver will use the the provided -// fallbackResolver for resolution. +// 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. // -// fallbackResolver must not be nil -func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions, fallbackResolver EndpointResolver) EndpointResolver { +// 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 { @@ -176,7 +166,6 @@ func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptio return &wrappedEndpointResolver{ awsResolver: resolver, - resolver: fallbackResolver, } } @@ -198,3 +187,332 @@ func finalizeClientEndpointResolverOptions(options *Options) { } } + +func resolveEndpointResolverV2(options *Options) { + if options.EndpointResolverV2 == nil { + options.EndpointResolverV2 = NewDefaultEndpointResolverV2() + } +} + +// Utility function to aid with translating pseudo-regions to classical regions +// with the appropriate setting indicated by the pseudo-region +func mapPseudoRegion(pr string) (region string, fips aws.FIPSEndpointState) { + const fipsInfix = "-fips-" + const fipsPrefix = "fips-" + const fipsSuffix = "-fips" + + if strings.Contains(pr, fipsInfix) || + strings.Contains(pr, fipsPrefix) || + strings.Contains(pr, fipsSuffix) { + region = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll( + pr, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "") + fips = aws.FIPSEndpointStateEnabled + } else { + region = pr + } + + return region, fips +} + +// builtInParameterResolver is the interface responsible for resolving BuiltIn +// values during the sourcing of EndpointParameters +type builtInParameterResolver interface { + ResolveBuiltIns(*EndpointParameters) error +} + +// builtInResolver resolves modeled BuiltIn values using only the members defined +// below. +type builtInResolver struct { + // The AWS region used to dispatch the request. + Region string + + // Sourced BuiltIn value in a historical enabled or disabled state. + UseDualStack aws.DualStackEndpointState + + // Sourced BuiltIn value in a historical enabled or disabled state. + UseFIPS aws.FIPSEndpointState + + // Base endpoint that can potentially be modified during Endpoint resolution. + Endpoint *string +} + +// Invoked at runtime to resolve BuiltIn Values. Only resolution code specific to +// each BuiltIn value is generated. +func (b *builtInResolver) ResolveBuiltIns(params *EndpointParameters) error { + + region, _ := mapPseudoRegion(b.Region) + if len(region) == 0 { + return fmt.Errorf("Could not resolve AWS::Region") + } else { + params.Region = aws.String(region) + } + if b.UseDualStack == aws.DualStackEndpointStateEnabled { + params.UseDualStack = aws.Bool(true) + } else { + params.UseDualStack = aws.Bool(false) + } + if b.UseFIPS == aws.FIPSEndpointStateEnabled { + params.UseFIPS = aws.Bool(true) + } else { + params.UseFIPS = aws.Bool(false) + } + params.Endpoint = b.Endpoint + return 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 +} + +// 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 +} + +// 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://api.ecr-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" == _PartitionResult.Name { + uriString := func() string { + var out strings.Builder + out.WriteString("https://ecr-fips.") + 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 + } + if "aws-us-gov" == _PartitionResult.Name { + uriString := func() string { + var out strings.Builder + out.WriteString("https://ecr-fips.") + 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://api.ecr-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://api.ecr.") + 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://api.ecr.") + 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") +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/generated.json index 631a65bba..0b78f9a89 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/generated.json @@ -4,6 +4,7 @@ "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", + "github.com/google/go-cmp": "v0.5.4", "github.com/jmespath/go-jmespath": "v0.4.0" }, "files": [ @@ -53,6 +54,7 @@ "deserializers.go", "doc.go", "endpoints.go", + "endpoints_test.go", "generated.json", "internal/endpoints/endpoints.go", "internal/endpoints/endpoints_test.go", diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/go_module_metadata.go index 15f5d82d5..f6cad4479 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/go_module_metadata.go @@ -3,4 +3,4 @@ package ecr // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.18.7" +const goModuleVersion = "1.20.2" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints/endpoints.go index 53aaf4cf2..ca046cf69 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints/endpoints.go @@ -89,13 +89,17 @@ var partitionRegexp = struct { 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)\\-\\w+\\-\\d+$"), + Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il)\\-\\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+$"), } @@ -439,6 +443,14 @@ var defaultPartitions = endpoints.Partitions{ }, Deprecated: aws.TrueTernary, }, + endpoints.EndpointKey{ + Region: "il-central-1", + }: endpoints.Endpoint{ + Hostname: "api.ecr.il-central-1.amazonaws.com", + CredentialScope: endpoints.CredentialScope{ + Region: "il-central-1", + }, + }, endpoints.EndpointKey{ Region: "me-central-1", }: endpoints.Endpoint{ @@ -656,6 +668,48 @@ var defaultPartitions = endpoints.Partitions{ }, }, }, + { + ID: "aws-iso-e", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "api.ecr-fips.{region}.cloud.adc-e.uk", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "api.ecr.{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: "api.ecr-fips.{region}.csp.hci.ic.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "api.ecr.{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{ diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go index 9356aabf1..d782c4ec9 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go @@ -154,9 +154,10 @@ const ( LifecyclePolicyPreviewStatusFailed LifecyclePolicyPreviewStatus = "FAILED" ) -// Values returns all known values for LifecyclePolicyPreviewStatus. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. +// Values returns all known values for LifecyclePolicyPreviewStatus. Note that +// this can be expanded in the future, and so it is only as up to date as the +// client. The ordering of this slice is not guaranteed to be stable across +// updates. func (LifecyclePolicyPreviewStatus) Values() []LifecyclePolicyPreviewStatus { return []LifecyclePolicyPreviewStatus{ "IN_PROGRESS", @@ -246,9 +247,10 @@ const ( ScanningRepositoryFilterTypeWildcard ScanningRepositoryFilterType = "WILDCARD" ) -// Values returns all known values for ScanningRepositoryFilterType. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. +// Values returns all known values for ScanningRepositoryFilterType. Note that +// this can be expanded in the future, and so it is only as up to date as the +// client. The ordering of this slice is not guaranteed to be stable across +// updates. func (ScanningRepositoryFilterType) Values() []ScanningRepositoryFilterType { return []ScanningRepositoryFilterType{ "WILDCARD", @@ -312,9 +314,9 @@ const ( TagStatusAny TagStatus = "ANY" ) -// Values returns all known values for TagStatus. Note that this can be expanded in -// the future, and so it is only as up to date as the client. The ordering of this -// slice is not guaranteed to be stable across updates. +// Values returns all known values for TagStatus. Note that this can be expanded +// in the future, and so it is only as up to date as the client. The ordering of +// this slice is not guaranteed to be stable across updates. func (TagStatus) Values() []TagStatus { return []TagStatus{ "TAGGED", diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/errors.go index 3f72008bd..4b4782c5a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/errors.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/errors.go @@ -167,8 +167,8 @@ func (e *InvalidLayerException) ErrorCode() string { } func (e *InvalidLayerException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The layer part size is not valid, or the first byte specified is not consecutive -// to the last byte of a previous layer part upload. +// The layer part size is not valid, or the first byte specified is not +// consecutive to the last byte of a previous layer part upload. type InvalidLayerPartException struct { Message *string @@ -308,8 +308,8 @@ func (e *LayerAlreadyExistsException) ErrorCode() string { } func (e *LayerAlreadyExistsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The specified layer is not available because it is not associated with an image. -// Unassociated image layers may be cleaned up at any time. +// The specified layer is not available because it is not associated with an +// image. Unassociated image layers may be cleaned up at any time. type LayerInaccessibleException struct { Message *string @@ -361,8 +361,8 @@ func (e *LayerPartTooSmallException) ErrorCode() string { } func (e *LayerPartTooSmallException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The specified layers could not be found, or the specified layer is not valid for -// this repository. +// The specified layers could not be found, or the specified layer is not valid +// for this repository. type LayersNotFoundException struct { Message *string @@ -471,10 +471,9 @@ func (e *LifecyclePolicyPreviewNotFoundException) ErrorFault() smithy.ErrorFault return smithy.FaultClient } -// The operation did not succeed because it would have exceeded a service limit for -// your account. For more information, see Amazon ECR service quotas -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service-quotas.html) in -// the Amazon Elastic Container Registry User Guide. +// The operation did not succeed because it would have exceeded a service limit +// for your account. For more information, see Amazon ECR service quotas (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service-quotas.html) +// in the Amazon Elastic Container Registry User Guide. type LimitExceededException struct { Message *string @@ -663,9 +662,9 @@ func (e *RepositoryNotEmptyException) ErrorCode() string { } func (e *RepositoryNotEmptyException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The specified repository could not be found. Check the spelling of the specified -// repository and ensure that you are performing operations on the correct -// registry. +// The specified repository could not be found. Check the spelling of the +// specified repository and ensure that you are performing operations on the +// correct registry. type RepositoryNotFoundException struct { Message *string @@ -771,8 +770,8 @@ func (e *ServerException) ErrorCode() string { } func (e *ServerException) ErrorFault() smithy.ErrorFault { return smithy.FaultServer } -// The list of tags on the repository is over the limit. The maximum number of tags -// that can be applied to a repository is 50. +// The list of tags on the repository is over the limit. The maximum number of +// tags that can be applied to a repository is 50. type TooManyTagsException struct { Message *string diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go index 22afaab80..1dbaf7725 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go @@ -26,7 +26,7 @@ type AuthorizationData struct { // A base64-encoded string that contains authorization data for the specified // Amazon ECR registry. When the string is decoded, it is presented in the format - // user:password for private registry authentication using docker login. + // user:password for private registry authentication using docker login . AuthorizationToken *string // The Unix time in seconds and milliseconds when the authorization token expires. @@ -35,8 +35,8 @@ type AuthorizationData struct { // The registry URL to use for this authorization token in a docker login command. // The Amazon ECR registry URL format is - // https://aws_account_id.dkr.ecr.region.amazonaws.com. For example, - // https://012345678910.dkr.ecr.us-east-1.amazonaws.com.. + // https://aws_account_id.dkr.ecr.region.amazonaws.com . For example, + // https://012345678910.dkr.ecr.us-east-1.amazonaws.com .. ProxyEndpoint *string noSmithyDocumentSerde @@ -128,7 +128,7 @@ type CvssScoreDetails struct { type DescribeImagesFilter struct { // The tag status with which to filter your DescribeImages results. You can filter - // results based on whether they are TAGGED or UNTAGGED. + // results based on whether they are TAGGED or UNTAGGED . TagStatus TagStatus noSmithyDocumentSerde @@ -142,8 +142,7 @@ type DescribeImagesFilter struct { // require any action on your part. For more control over the encryption of the // contents of your repository, you can use server-side encryption with Key // Management Service key stored in Key Management Service (KMS) to encrypt your -// images. For more information, see Amazon ECR encryption at rest -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/encryption-at-rest.html) +// images. For more information, see Amazon ECR encryption at rest (https://docs.aws.amazon.com/AmazonECR/latest/userguide/encryption-at-rest.html) // in the Amazon Elastic Container Registry User Guide. type EncryptionConfiguration struct { @@ -153,14 +152,12 @@ type EncryptionConfiguration struct { // can either use the default Amazon Web Services managed KMS key for Amazon ECR, // or specify your own KMS key, which you already created. For more information, // see Protecting data using server-side encryption with an KMS key stored in Key - // Management Service (SSE-KMS) - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html) in the - // Amazon Simple Storage Service Console Developer Guide. If you use the AES256 - // encryption type, Amazon ECR uses server-side encryption with Amazon S3-managed - // encryption keys which encrypts the images in the repository using an AES-256 - // encryption algorithm. For more information, see Protecting data using - // server-side encryption with Amazon S3-managed encryption keys (SSE-S3) - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html) + // Management Service (SSE-KMS) (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html) + // in the Amazon Simple Storage Service Console Developer Guide. If you use the + // AES256 encryption type, Amazon ECR uses server-side encryption with Amazon + // S3-managed encryption keys which encrypts the images in the repository using an + // AES-256 encryption algorithm. For more information, see Protecting data using + // server-side encryption with Amazon S3-managed encryption keys (SSE-S3) (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html) // in the Amazon Simple Storage Service Console Developer Guide. // // This member is required. @@ -276,19 +273,19 @@ type ImageDetail struct { // Docker version 1.9, the Docker client compresses image layers before pushing // them to a V2 Docker registry. The output of the docker images command shows the // uncompressed image size, so it may return a larger image size than the image - // sizes returned by DescribeImages. + // sizes returned by DescribeImages . ImageSizeInBytes *int64 // The list of tags associated with this image. ImageTags []string - // The date and time, expressed in standard JavaScript date format, when Amazon ECR - // recorded the last image pull. Amazon ECR refreshes the last image pull timestamp - // at least once every 24 hours. For example, if you pull an image once a day then - // the lastRecordedPullTime timestamp will indicate the exact time that the image - // was last pulled. However, if you pull an image once an hour, because Amazon ECR - // refreshes the lastRecordedPullTime timestamp at least once every 24 hours, the - // result may not be the exact time that the image was last pulled. + // The date and time, expressed in standard JavaScript date format, when Amazon + // ECR recorded the last image pull. Amazon ECR refreshes the last image pull + // timestamp at least once every 24 hours. For example, if you pull an image once a + // day then the lastRecordedPullTime timestamp will indicate the exact time that + // the image was last pulled. However, if you pull an image once an hour, because + // Amazon ECR refreshes the lastRecordedPullTime timestamp at least once every 24 + // hours, the result may not be the exact time that the image was last pulled. LastRecordedPullTime *time.Time // The Amazon Web Services account ID associated with the registry to which this @@ -408,10 +405,9 @@ type ImageScanFindingsSummary struct { type ImageScanningConfiguration struct { // The setting that determines whether images are scanned after being pushed to a - // repository. If set to true, images will be scanned after being pushed. If this + // repository. If set to true , images will be scanned after being pushed. If this // parameter is not specified, it will default to false and images will not be - // scanned unless a scan is manually started with the API_StartImageScan - // (https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_StartImageScan.html) + // scanned unless a scan is manually started with the API_StartImageScan (https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_StartImageScan.html) // API. ScanOnPush bool @@ -444,7 +440,7 @@ type Layer struct { // The media type of the layer, such as // application/vnd.docker.image.rootfs.diff.tar.gzip or - // application/vnd.oci.image.layer.v1.tar+gzip. + // application/vnd.oci.image.layer.v1.tar+gzip . MediaType *string noSmithyDocumentSerde @@ -518,7 +514,7 @@ type LifecyclePolicyRuleAction struct { type ListImagesFilter struct { // The tag status with which to filter your ListImages results. You can filter - // results based on whether they are TAGGED or UNTAGGED. + // results based on whether they are TAGGED or UNTAGGED . TagStatus TagStatus noSmithyDocumentSerde @@ -570,8 +566,8 @@ type PullThroughCacheRule struct { // The Amazon ECR repository prefix associated with the pull through cache rule. EcrRepositoryPrefix *string - // The Amazon Web Services account ID associated with the registry the pull through - // cache rule is associated with. + // The Amazon Web Services account ID associated with the registry the pull + // through cache rule is associated with. RegistryId *string // The upstream registry URL associated with the pull through cache rule. @@ -615,8 +611,9 @@ type RegistryScanningRule struct { // The frequency that scans are performed at for a private registry. When the // ENHANCED scan type is specified, the supported scan frequencies are - // CONTINUOUS_SCAN and SCAN_ON_PUSH. When the BASIC scan type is specified, the - // SCAN_ON_PUSH and MANUAL scan frequencies are supported. + // CONTINUOUS_SCAN and SCAN_ON_PUSH . When the BASIC scan type is specified, the + // SCAN_ON_PUSH scan frequency is supported. If scan on push is not specified, then + // the MANUAL scan frequency is set by default. // // This member is required. ScanFrequency ScanFrequency @@ -704,7 +701,8 @@ type Repository struct { // The Amazon Resource Name (ARN) that identifies the repository. The ARN contains // the arn:aws:ecr namespace, followed by the region of the repository, Amazon Web // Services account ID of the repository owner, repository namespace, and - // repository name. For example, arn:aws:ecr:region:012345678910:repository/test. + // repository name. For example, + // arn:aws:ecr:region:012345678910:repository-namespace/repository-name . RepositoryArn *string // The name of the repository. @@ -719,8 +717,8 @@ type Repository struct { // The filter settings used with image replication. Specifying a repository filter // to a replication rule provides a method for controlling which repositories in a -// private registry are replicated. If no repository filter is specified, all -// images in the repository are replicated. +// private registry are replicated. If no filters are added, the contents of all +// repositories are replicated. type RepositoryFilter struct { // The repository filter details. When the PREFIX_MATCH filter type is specified, @@ -730,8 +728,8 @@ type RepositoryFilter struct { // This member is required. Filter *string - // The repository filter type. The only supported value is PREFIX_MATCH, which is a - // repository name prefix specified with the filter parameter. + // The repository filter type. The only supported value is PREFIX_MATCH , which is + // a repository name prefix specified with the filter parameter. // // This member is required. FilterType RepositoryFilterType @@ -797,16 +795,15 @@ type Resource struct { // Contains details about the resource involved in the finding. type ResourceDetails struct { - // An object that contains details about the Amazon ECR container image involved in - // the finding. + // An object that contains details about the Amazon ECR container image involved + // in the finding. AwsEcrContainerImage *AwsEcrContainerImageDetails noSmithyDocumentSerde } // The details of a scanning repository filter. For more information on how to use -// filters, see Using filters -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html#image-scanning-filters) +// filters, see Using filters (https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html#image-scanning-filters) // in the Amazon Elastic Container Registry User Guide. type ScanningRepositoryFilter struct { @@ -840,9 +837,13 @@ type Tag struct { // One part of a key-value pair that make up a tag. A key is a general label that // acts like a category for more specific tag values. + // + // This member is required. Key *string // A value acts as a descriptor within a tag category (key). + // + // This member is required. Value *string noSmithyDocumentSerde diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/validators.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/validators.go index 9baf8c8cf..754611f1c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/validators.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/validators.go @@ -1045,6 +1045,41 @@ func validateScanningRepositoryFilterList(v []types.ScanningRepositoryFilter) er } } +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 validateTagList(v []types.Tag) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "TagList"} + 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 validateOpBatchCheckLayerAvailabilityInput(v *BatchCheckLayerAvailabilityInput) error { if v == nil { return nil @@ -1161,6 +1196,11 @@ func validateOpCreateRepositoryInput(v *CreateRepositoryInput) error { if v.RepositoryName == nil { invalidParams.Add(smithy.NewErrParamRequired("RepositoryName")) } + if v.Tags != nil { + if err := validateTagList(v.Tags); err != nil { + invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) + } + } if v.EncryptionConfiguration != nil { if err := validateEncryptionConfiguration(v.EncryptionConfiguration); err != nil { invalidParams.AddNested("EncryptionConfiguration", err.(smithy.InvalidParamsError)) @@ -1576,6 +1616,10 @@ func validateOpTagResourceInput(v *TagResourceInput) error { } if v.Tags == nil { invalidParams.Add(smithy.NewErrParamRequired("Tags")) + } else if v.Tags != nil { + if err := validateTagList(v.Tags); err != nil { + invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) + } } if invalidParams.Len() > 0 { return invalidParams diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/CHANGELOG.md index b6ad151e8..b3b5a57e6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/CHANGELOG.md @@ -1,3 +1,203 @@ +# v1.18.2 (2023-10-12) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.1 (2023-10-06) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.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.17.5 (2023-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.17.4 (2023-08-18) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.17.3 (2023-08-17) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.17.2 (2023-08-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.17.1 (2023-08-01) + +* No change notes available for this release. + +# v1.17.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.16.6 (2023-07-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.16.5 (2023-07-13) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.16.4 (2023-06-15) + +* No change notes available for this release. + +# v1.16.3 (2023-06-13) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.16.2 (2023-05-04) + +* No change notes available for this release. + +# v1.16.1 (2023-04-24) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.16.0 (2023-04-11) + +* **Feature**: This release will allow using registry alias as registryId in BatchDeleteImage request. + +# v1.15.8 (2023-04-10) + +* No change notes available for this release. + +# v1.15.7 (2023-04-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.15.6 (2023-03-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.15.5 (2023-03-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.15.4 (2023-02-22) + +* **Bug Fix**: Prevent nil pointer dereference when retrieving error codes. + +# v1.15.3 (2023-02-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.15.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.15.1 (2023-02-03) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.15.0 (2023-01-09) + +* **Feature**: This release for Amazon ECR Public makes several change to bring the SDK into sync with the API. + +# v1.14.0 (2023-01-05) + +* **Feature**: Add `ErrorCodeOverride` field to all error structs (aws/smithy-go#401). + +# v1.13.22 (2022-12-15) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.21 (2022-12-02) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.20 (2022-11-30) + +* No change notes available for this release. + +# v1.13.19 (2022-10-24) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.18 (2022-10-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.17 (2022-09-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.16 (2022-09-14) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.15 (2022-09-02) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.14 (2022-08-31) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.13 (2022-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.12 (2022-08-11) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.11 (2022-08-09) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.10 (2022-08-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.9 (2022-08-01) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.8 (2022-07-05) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.7 (2022-06-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.6 (2022-06-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.5 (2022-05-17) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.4 (2022-04-25) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.3 (2022-03-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.2 (2022-03-24) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.1 (2022-03-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.0 (2022-03-08) + +* **Feature**: Updated `github.com/aws/smithy-go` to latest version +* **Dependency Update**: Updated to the latest SDK module versions + # v1.12.0 (2022-02-24) * **Feature**: API client updated diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_client.go index dfd012e2f..a8264f47a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_client.go @@ -4,6 +4,7 @@ package ecrpublic import ( "context" + "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" @@ -46,8 +47,6 @@ func New(options Options, optFns ...func(*Options)) *Client { resolveHTTPSignerV4(&options) - resolveDefaultEndpointConfiguration(&options) - for _, fn := range optFns { fn(&options) } @@ -65,6 +64,14 @@ type Options struct { // 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 @@ -79,8 +86,18 @@ type Options struct { 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. This should be used over + // the deprecated EndpointResolver + EndpointResolverV2 EndpointResolverV2 + // Signature Version 4 (SigV4) Signer HTTPSignerV4 HTTPSignerV4 @@ -115,7 +132,7 @@ type Options struct { Retryer aws.Retryer // The RuntimeEnvironment configuration, only populated if the DefaultsMode is set - // to DefaultsModeAuto and is initialized using config.LoadDefaultConfig. You + // 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 @@ -139,14 +156,25 @@ func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { } } -// WithEndpointResolver returns a functional option for setting the Client's -// EndpointResolver option. +// 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 + } +} + type HTTPClient interface { Do(*http.Request) (*http.Response, error) } @@ -163,6 +191,8 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf ctx = middleware.ClearStackValues(ctx) stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) options := c.options.Copy() + resolveEndpointResolverV2(&options) + for _, fn := range optFns { fn(&options) } @@ -197,6 +227,30 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf 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 @@ -234,6 +288,7 @@ func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { APIOptions: cfg.APIOptions, Logger: cfg.Logger, ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) @@ -344,11 +399,19 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil { return } - o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions, NewDefaultEndpointResolver()) + o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) } -func addClientUserAgent(stack *middleware.Stack) error { - return awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "ecrpublic", goModuleVersion)(stack) +func addClientUserAgent(stack *middleware.Stack, options Options) error { + if err := awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "ecrpublic", goModuleVersion)(stack); err != nil { + return err + } + + if len(options.AppID) > 0 { + return awsmiddleware.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID)(stack) + } + + return nil } func addHTTPSignerV4Middleware(stack *middleware.Stack, o Options) error { @@ -432,3 +495,32 @@ func addRequestResponseLogging(stack *middleware.Stack, o Options) error { LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), }, middleware.After) } + +type endpointDisableHTTPSMiddleware struct { + EndpointDisableHTTPS bool +} + +func (*endpointDisableHTTPSMiddleware) ID() string { + return "endpointDisableHTTPSMiddleware" +} + +func (m *endpointDisableHTTPSMiddleware) 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) + } + + if m.EndpointDisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) { + req.URL.Scheme = "http" + } + + return next.HandleSerialize(ctx, in) + +} +func addendpointDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { + return stack.Serialize.Insert(&endpointDisableHTTPSMiddleware{ + EndpointDisableHTTPS: o.EndpointOptions.DisableHTTPS, + }, "OperationSerializer", middleware.Before) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchCheckLayerAvailability.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchCheckLayerAvailability.go index 682599a03..d0d042e49 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchCheckLayerAvailability.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchCheckLayerAvailability.go @@ -4,19 +4,24 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Checks the availability of one or more image layers within a repository in a -// public registry. When an image is pushed to a repository, each image layer is -// checked to verify if it has been uploaded before. If it has been uploaded, then -// the image layer is skipped. This operation is used by the Amazon ECR proxy and -// is not generally used by customers for pulling and pushing images. In most -// cases, you should use the docker CLI to pull, tag, and push images. +// Checks the availability of one or more image layers that are within a +// repository in a public registry. When an image is pushed to a repository, each +// image layer is checked to verify if it has been uploaded before. If it has been +// uploaded, then the image layer is skipped. This operation is used by the Amazon +// ECR proxy and is not generally used by customers for pulling and pushing images. +// In most cases, you should use the docker CLI to pull, tag, and push images. func (c *Client) BatchCheckLayerAvailability(ctx context.Context, params *BatchCheckLayerAvailabilityInput, optFns ...func(*Options)) (*BatchCheckLayerAvailabilityOutput, error) { if params == nil { params = &BatchCheckLayerAvailabilityInput{} @@ -39,14 +44,14 @@ type BatchCheckLayerAvailabilityInput struct { // This member is required. LayerDigests []string - // The name of the repository that is associated with the image layers to check. + // The name of the repository that's associated with the image layers to check. // // This member is required. RepositoryName *string - // The AWS account ID associated with the public registry that contains the image - // layers to check. If you do not specify a registry, the default public registry - // is assumed. + // The Amazon Web Services account ID, or registry alias, associated with the + // public registry that contains the image layers to check. If you do not specify a + // registry, the default public registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -57,8 +62,8 @@ type BatchCheckLayerAvailabilityOutput struct { // Any failures associated with the call. Failures []types.LayerFailure - // A list of image layer objects corresponding to the image layer references in the - // request. + // A list of image layer objects that correspond to the image layer references in + // the request. Layers []types.Layer // Metadata pertaining to the operation's result. @@ -76,6 +81,9 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -103,7 +111,7 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -112,12 +120,18 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addBatchCheckLayerAvailabilityResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpBatchCheckLayerAvailabilityValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opBatchCheckLayerAvailability(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -127,6 +141,9 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -138,3 +155,126 @@ func newServiceMetadataMiddleware_opBatchCheckLayerAvailability(region string) * OperationName: "BatchCheckLayerAvailability", } } + +type opBatchCheckLayerAvailabilityResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opBatchCheckLayerAvailabilityResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opBatchCheckLayerAvailabilityResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addBatchCheckLayerAvailabilityResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opBatchCheckLayerAvailabilityResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchDeleteImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchDeleteImage.go index b208c9520..1ec61e3f9 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchDeleteImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchDeleteImage.go @@ -4,19 +4,24 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Deletes a list of specified images within a repository in a public registry. -// Images are specified with either an imageTag or imageDigest. You can remove a -// tag from an image by specifying the image's tag in your request. When you remove -// the last tag from an image, the image is deleted from your repository. You can -// completely delete an image (and all of its tags) by specifying the image's -// digest in your request. +// Deletes a list of specified images that are within a repository in a public +// registry. Images are specified with either an imageTag or imageDigest . You can +// remove a tag from an image by specifying the image's tag in your request. When +// you remove the last tag from an image, the image is deleted from your +// repository. You can completely delete an image (and all of its tags) by +// specifying the digest of the image in your request. func (c *Client) BatchDeleteImage(ctx context.Context, params *BatchDeleteImageInput, optFns ...func(*Options)) (*BatchDeleteImageOutput, error) { if params == nil { params = &BatchDeleteImageInput{} @@ -34,8 +39,8 @@ func (c *Client) BatchDeleteImage(ctx context.Context, params *BatchDeleteImageI type BatchDeleteImageInput struct { - // A list of image ID references that correspond to images to delete. The format of - // the imageIds reference is imageTag=tag or imageDigest=digest. + // A list of image ID references that correspond to images to delete. The format + // of the imageIds reference is imageTag=tag or imageDigest=digest . // // This member is required. ImageIds []types.ImageIdentifier @@ -45,9 +50,9 @@ type BatchDeleteImageInput struct { // This member is required. RepositoryName *string - // The AWS account ID associated with the registry that contains the image to - // delete. If you do not specify a registry, the default public registry is - // assumed. + // The Amazon Web Services account ID, or registry alias, that's associated with + // the registry that contains the image to delete. If you do not specify a + // registry, the default public registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -76,6 +81,9 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -103,7 +111,7 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -112,12 +120,18 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addBatchDeleteImageResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpBatchDeleteImageValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opBatchDeleteImage(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -127,6 +141,9 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -138,3 +155,126 @@ func newServiceMetadataMiddleware_opBatchDeleteImage(region string) *awsmiddlewa OperationName: "BatchDeleteImage", } } + +type opBatchDeleteImageResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opBatchDeleteImageResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opBatchDeleteImageResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addBatchDeleteImageResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opBatchDeleteImageResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CompleteLayerUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CompleteLayerUpload.go index 206e55f52..3e93650ab 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CompleteLayerUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CompleteLayerUpload.go @@ -4,17 +4,22 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Informs Amazon ECR that the image layer upload has completed for a specified +// Informs Amazon ECR that the image layer upload is complete for a specified // public registry, repository name, and upload ID. You can optionally provide a // sha256 digest of the image layer for data validation purposes. When an image is -// pushed, the CompleteLayerUpload API is called once per each new image layer to -// verify that the upload has completed. This operation is used by the Amazon ECR +// pushed, the CompleteLayerUpload API is called once for each new image layer to +// verify that the upload is complete. This operation is used by the Amazon ECR // proxy and is not generally used by customers for pulling and pushing images. In // most cases, you should use the docker CLI to pull, tag, and push images. func (c *Client) CompleteLayerUpload(ctx context.Context, params *CompleteLayerUploadInput, optFns ...func(*Options)) (*CompleteLayerUploadOutput, error) { @@ -51,8 +56,9 @@ type CompleteLayerUploadInput struct { // This member is required. UploadId *string - // The AWS account ID associated with the registry to which to upload layers. If - // you do not specify a registry, the default public registry is assumed. + // The Amazon Web Services account ID, or registry alias, associated with the + // registry where layers are uploaded. If you do not specify a registry, the + // default public registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -63,13 +69,13 @@ type CompleteLayerUploadOutput struct { // The sha256 digest of the image layer. LayerDigest *string - // The public registry ID associated with the request. + // The public registry ID that's associated with the request. RegistryId *string - // The repository name associated with the request. + // The repository name that's associated with the request. RepositoryName *string - // The upload ID associated with the layer. + // The upload ID that's associated with the layer. UploadId *string // Metadata pertaining to the operation's result. @@ -87,6 +93,9 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -114,7 +123,7 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -123,12 +132,18 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addCompleteLayerUploadResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpCompleteLayerUploadValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCompleteLayerUpload(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -138,6 +153,9 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -149,3 +167,126 @@ func newServiceMetadataMiddleware_opCompleteLayerUpload(region string) *awsmiddl OperationName: "CompleteLayerUpload", } } + +type opCompleteLayerUploadResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opCompleteLayerUploadResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opCompleteLayerUploadResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addCompleteLayerUploadResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opCompleteLayerUploadResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CreateRepository.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CreateRepository.go index 82a2a7e5f..082ffca47 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CreateRepository.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CreateRepository.go @@ -4,17 +4,21 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Creates a repository in a public registry. For more information, see Amazon ECR -// repositories -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/Repositories.html) in -// the Amazon Elastic Container Registry User Guide. +// repositories (https://docs.aws.amazon.com/AmazonECR/latest/userguide/Repositories.html) +// in the Amazon Elastic Container Registry User Guide. func (c *Client) CreateRepository(ctx context.Context, params *CreateRepositoryInput, optFns ...func(*Options)) (*CreateRepositoryOutput, error) { if params == nil { params = &CreateRepositoryInput{} @@ -33,9 +37,9 @@ func (c *Client) CreateRepository(ctx context.Context, params *CreateRepositoryI type CreateRepositoryInput struct { // The name to use for the repository. This appears publicly in the Amazon ECR - // Public Gallery. The repository name may be specified on its own (such as - // nginx-web-app) or it can be prepended with a namespace to group the repository - // into a category (such as project-a/nginx-web-app). + // Public Gallery. The repository name can be specified on its own (for example + // nginx-web-app ) or prepended with a namespace to group the repository into a + // category (for example project-a/nginx-web-app ). // // This member is required. RepositoryName *string @@ -44,10 +48,10 @@ type CreateRepositoryInput struct { // Public Gallery. CatalogData *types.RepositoryCatalogDataInput - // The metadata that you apply to the repository to help you categorize and - // organize them. Each tag consists of a key and an optional value, both of which - // you define. Tag keys can have a maximum character length of 128 characters, and - // tag values can have a maximum length of 256 characters. + // The metadata that you apply to each repository to help categorize and organize + // your repositories. Each tag consists of a key and an optional value. You define + // both of them. Tag keys can have a maximum character length of 128 characters, + // and tag values can have a maximum length of 256 characters. Tags []types.Tag noSmithyDocumentSerde @@ -77,6 +81,9 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -104,7 +111,7 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -113,12 +120,18 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addCreateRepositoryResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpCreateRepositoryValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateRepository(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -128,6 +141,9 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -139,3 +155,126 @@ func newServiceMetadataMiddleware_opCreateRepository(region string) *awsmiddlewa OperationName: "CreateRepository", } } + +type opCreateRepositoryResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opCreateRepositoryResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opCreateRepositoryResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addCreateRepositoryResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opCreateRepositoryResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepository.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepository.go index 30503d3b7..6f25f9010 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepository.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepository.go @@ -4,16 +4,22 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Deletes a repository in a public registry. If the repository contains images, -// you must either delete all images in the repository or use the force option -// which deletes all images on your behalf before deleting the repository. +// you must either manually delete all images in the repository or use the force +// option. This option deletes all images on your behalf before deleting the +// repository. func (c *Client) DeleteRepository(ctx context.Context, params *DeleteRepositoryInput, optFns ...func(*Options)) (*DeleteRepositoryOutput, error) { if params == nil { params = &DeleteRepositoryInput{} @@ -36,12 +42,13 @@ type DeleteRepositoryInput struct { // This member is required. RepositoryName *string - // If a repository contains images, forces the deletion. + // The force option can be used to delete a repository that contains images. If + // the force option is not used, the repository must be empty prior to deletion. Force bool - // The AWS account ID associated with the public registry that contains the - // repository to delete. If you do not specify a registry, the default public - // registry is assumed. + // The Amazon Web Services account ID that's associated with the public registry + // that contains the repository to delete. If you do not specify a registry, the + // default public registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -67,6 +74,9 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -94,7 +104,7 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -103,12 +113,18 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDeleteRepositoryResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteRepositoryValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteRepository(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -118,6 +134,9 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -129,3 +148,126 @@ func newServiceMetadataMiddleware_opDeleteRepository(region string) *awsmiddlewa OperationName: "DeleteRepository", } } + +type opDeleteRepositoryResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteRepositoryResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteRepositoryResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteRepositoryResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteRepositoryResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepositoryPolicy.go index b6ce507b7..a8f26b837 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepositoryPolicy.go @@ -4,13 +4,18 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Deletes the repository policy associated with the specified repository. +// Deletes the repository policy that's associated with the specified repository. func (c *Client) DeleteRepositoryPolicy(ctx context.Context, params *DeleteRepositoryPolicyInput, optFns ...func(*Options)) (*DeleteRepositoryPolicyOutput, error) { if params == nil { params = &DeleteRepositoryPolicyInput{} @@ -28,15 +33,15 @@ func (c *Client) DeleteRepositoryPolicy(ctx context.Context, params *DeleteRepos type DeleteRepositoryPolicyInput struct { - // The name of the repository that is associated with the repository policy to + // The name of the repository that's associated with the repository policy to // delete. // // This member is required. RepositoryName *string - // The AWS account ID associated with the public registry that contains the - // repository policy to delete. If you do not specify a registry, the default - // public registry is assumed. + // The Amazon Web Services account ID that's associated with the public registry + // that contains the repository policy to delete. If you do not specify a registry, + // the default public registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -47,10 +52,10 @@ type DeleteRepositoryPolicyOutput struct { // The JSON repository policy that was deleted from the repository. PolicyText *string - // The registry ID associated with the request. + // The registry ID that's associated with the request. RegistryId *string - // The repository name associated with the request. + // The repository name that's associated with the request. RepositoryName *string // Metadata pertaining to the operation's result. @@ -68,6 +73,9 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -95,7 +103,7 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -104,12 +112,18 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDeleteRepositoryPolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteRepositoryPolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteRepositoryPolicy(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -119,6 +133,9 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -130,3 +147,126 @@ func newServiceMetadataMiddleware_opDeleteRepositoryPolicy(region string) *awsmi OperationName: "DeleteRepositoryPolicy", } } + +type opDeleteRepositoryPolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteRepositoryPolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteRepositoryPolicyResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteRepositoryPolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteRepositoryPolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImageTags.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImageTags.go index e59efd5ac..49847d27c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImageTags.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImageTags.go @@ -4,10 +4,14 @@ package ecrpublic import ( "context" + "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -35,26 +39,26 @@ type DescribeImageTagsInput struct { // This member is required. RepositoryName *string - // The maximum number of repository results returned by DescribeImageTags in - // paginated output. When this parameter is used, DescribeImageTags only returns - // maxResults results in a single page along with a nextToken response element. The - // remaining results of the initial request can be seen by sending another - // DescribeImageTags request with the returned nextToken value. This value can be - // between 1 and 1000. If this parameter is not used, then DescribeImageTags - // returns up to 100 results and a nextToken value, if applicable. This option - // cannot be used when you specify images with imageIds. + // The maximum number of repository results that's returned by DescribeImageTags + // in paginated output. When this parameter is used, DescribeImageTags only + // returns maxResults results in a single page along with a nextToken response + // element. You can see the remaining results of the initial request by sending + // another DescribeImageTags request with the returned nextToken value. This value + // can be between 1 and 1000. If this parameter isn't used, then DescribeImageTags + // returns up to 100 results and a nextToken value, if applicable. If you specify + // images with imageIds , you can't use this option. MaxResults *int32 - // The nextToken value returned from a previous paginated DescribeImageTags request - // where maxResults was used and the results exceeded the value of that parameter. - // Pagination continues from the end of the previous results that returned the - // nextToken value. This value is null when there are no more results to return. - // This option cannot be used when you specify images with imageIds. + // The nextToken value that's returned from a previous paginated DescribeImageTags + // request where maxResults was used and the results exceeded the value of that + // parameter. Pagination continues from the end of the previous results that + // returned the nextToken value. If there are no more results to return, this + // value is null . If you specify images with imageIds , you can't use this option. NextToken *string - // The AWS account ID associated with the public registry that contains the - // repository in which to describe images. If you do not specify a registry, the - // default public registry is assumed. + // The Amazon Web Services account ID that's associated with the public registry + // that contains the repository where images are described. If you do not specify a + // registry, the default public registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -66,9 +70,9 @@ type DescribeImageTagsOutput struct { ImageTagDetails []types.ImageTagDetail // The nextToken value to include in a future DescribeImageTags request. When the - // results of a DescribeImageTags request exceed maxResults, this value can be used - // to retrieve the next page of results. This value is null when there are no more - // results to return. + // results of a DescribeImageTags request exceed maxResults , you can use this + // value to retrieve the next page of results. If there are no more results to + // return, this value is null . NextToken *string // Metadata pertaining to the operation's result. @@ -86,6 +90,9 @@ func (c *Client) addOperationDescribeImageTagsMiddlewares(stack *middleware.Stac if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -113,7 +120,7 @@ func (c *Client) addOperationDescribeImageTagsMiddlewares(stack *middleware.Stac if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -122,12 +129,18 @@ func (c *Client) addOperationDescribeImageTagsMiddlewares(stack *middleware.Stac if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDescribeImageTagsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDescribeImageTagsValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeImageTags(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -137,6 +150,9 @@ func (c *Client) addOperationDescribeImageTagsMiddlewares(stack *middleware.Stac if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -150,14 +166,14 @@ var _ DescribeImageTagsAPIClient = (*Client)(nil) // DescribeImageTagsPaginatorOptions is the paginator options for DescribeImageTags type DescribeImageTagsPaginatorOptions struct { - // The maximum number of repository results returned by DescribeImageTags in - // paginated output. When this parameter is used, DescribeImageTags only returns - // maxResults results in a single page along with a nextToken response element. The - // remaining results of the initial request can be seen by sending another - // DescribeImageTags request with the returned nextToken value. This value can be - // between 1 and 1000. If this parameter is not used, then DescribeImageTags - // returns up to 100 results and a nextToken value, if applicable. This option - // cannot be used when you specify images with imageIds. + // The maximum number of repository results that's returned by DescribeImageTags + // in paginated output. When this parameter is used, DescribeImageTags only + // returns maxResults results in a single page along with a nextToken response + // element. You can see the remaining results of the initial request by sending + // another DescribeImageTags request with the returned nextToken value. This value + // can be between 1 and 1000. If this parameter isn't used, then DescribeImageTags + // returns up to 100 results and a nextToken value, if applicable. If you specify + // images with imageIds , you can't use this option. Limit int32 // Set to true if pagination should stop if the service returns a pagination token @@ -245,3 +261,126 @@ func newServiceMetadataMiddleware_opDescribeImageTags(region string) *awsmiddlew OperationName: "DescribeImageTags", } } + +type opDescribeImageTagsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDescribeImageTagsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDescribeImageTagsResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDescribeImageTagsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDescribeImageTagsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImages.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImages.go index 6d6df97a2..2060f6ed0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImages.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImages.go @@ -4,19 +4,23 @@ package ecrpublic import ( "context" + "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Returns metadata about the images in a repository in a public registry. -// Beginning with Docker version 1.9, the Docker client compresses image layers -// before pushing them to a V2 Docker registry. The output of the docker images -// command shows the uncompressed image size, so it may return a larger image size -// than the image sizes returned by DescribeImages. +// Returns metadata that's related to the images in a repository in a public +// registry. Beginning with Docker version 1.9, the Docker client compresses image +// layers before pushing them to a V2 Docker registry. The output of the docker +// images command shows the uncompressed image size. Therefore, it might return a +// larger image size than the image sizes that are returned by DescribeImages . func (c *Client) DescribeImages(ctx context.Context, params *DescribeImagesInput, optFns ...func(*Options)) (*DescribeImagesOutput, error) { if params == nil { params = &DescribeImagesInput{} @@ -42,26 +46,26 @@ type DescribeImagesInput struct { // The list of image IDs for the requested repository. ImageIds []types.ImageIdentifier - // The maximum number of repository results returned by DescribeImages in paginated - // output. When this parameter is used, DescribeImages only returns maxResults - // results in a single page along with a nextToken response element. The remaining - // results of the initial request can be seen by sending another DescribeImages - // request with the returned nextToken value. This value can be between 1 and 1000. - // If this parameter is not used, then DescribeImages returns up to 100 results and - // a nextToken value, if applicable. This option cannot be used when you specify - // images with imageIds. + // The maximum number of repository results that's returned by DescribeImages in + // paginated output. When this parameter is used, DescribeImages only returns + // maxResults results in a single page along with a nextToken response element. + // You can see the remaining results of the initial request by sending another + // DescribeImages request with the returned nextToken value. This value can be + // between 1 and 1000. If this parameter isn't used, then DescribeImages returns + // up to 100 results and a nextToken value, if applicable. If you specify images + // with imageIds , you can't use this option. MaxResults *int32 - // The nextToken value returned from a previous paginated DescribeImages request - // where maxResults was used and the results exceeded the value of that parameter. - // Pagination continues from the end of the previous results that returned the - // nextToken value. This value is null when there are no more results to return. - // This option cannot be used when you specify images with imageIds. + // The nextToken value that's returned from a previous paginated DescribeImages + // request where maxResults was used and the results exceeded the value of that + // parameter. Pagination continues from the end of the previous results that + // returned the nextToken value. If there are no more results to return, this + // value is null . If you specify images with imageIds , you can't use this option. NextToken *string - // The AWS account ID associated with the public registry that contains the - // repository in which to describe images. If you do not specify a registry, the - // default public registry is assumed. + // The Amazon Web Services account ID that's associated with the public registry + // that contains the repository where images are described. If you do not specify a + // registry, the default public registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -73,9 +77,9 @@ type DescribeImagesOutput struct { ImageDetails []types.ImageDetail // The nextToken value to include in a future DescribeImages request. When the - // results of a DescribeImages request exceed maxResults, this value can be used to - // retrieve the next page of results. This value is null when there are no more - // results to return. + // results of a DescribeImages request exceed maxResults , you can use this value + // to retrieve the next page of results. If there are no more results to return, + // this value is null . NextToken *string // Metadata pertaining to the operation's result. @@ -93,6 +97,9 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -120,7 +127,7 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -129,12 +136,18 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDescribeImagesResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDescribeImagesValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeImages(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -144,6 +157,9 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -157,14 +173,14 @@ var _ DescribeImagesAPIClient = (*Client)(nil) // DescribeImagesPaginatorOptions is the paginator options for DescribeImages type DescribeImagesPaginatorOptions struct { - // The maximum number of repository results returned by DescribeImages in paginated - // output. When this parameter is used, DescribeImages only returns maxResults - // results in a single page along with a nextToken response element. The remaining - // results of the initial request can be seen by sending another DescribeImages - // request with the returned nextToken value. This value can be between 1 and 1000. - // If this parameter is not used, then DescribeImages returns up to 100 results and - // a nextToken value, if applicable. This option cannot be used when you specify - // images with imageIds. + // The maximum number of repository results that's returned by DescribeImages in + // paginated output. When this parameter is used, DescribeImages only returns + // maxResults results in a single page along with a nextToken response element. + // You can see the remaining results of the initial request by sending another + // DescribeImages request with the returned nextToken value. This value can be + // between 1 and 1000. If this parameter isn't used, then DescribeImages returns + // up to 100 results and a nextToken value, if applicable. If you specify images + // with imageIds , you can't use this option. Limit int32 // Set to true if pagination should stop if the service returns a pagination token @@ -252,3 +268,126 @@ func newServiceMetadataMiddleware_opDescribeImages(region string) *awsmiddleware OperationName: "DescribeImages", } } + +type opDescribeImagesResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDescribeImagesResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDescribeImagesResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDescribeImagesResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDescribeImagesResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRegistries.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRegistries.go index e9297dfe9..6923ea084 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRegistries.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRegistries.go @@ -4,10 +4,14 @@ package ecrpublic import ( "context" + "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -30,21 +34,22 @@ func (c *Client) DescribeRegistries(ctx context.Context, params *DescribeRegistr type DescribeRegistriesInput struct { - // The maximum number of repository results returned by DescribeRegistries in - // paginated output. When this parameter is used, DescribeRegistries only returns - // maxResults results in a single page along with a nextToken response element. The - // remaining results of the initial request can be seen by sending another - // DescribeRegistries request with the returned nextToken value. This value can be - // between 1 and 1000. If this parameter is not used, then DescribeRegistries - // returns up to 100 results and a nextToken value, if applicable. + // The maximum number of repository results that's returned by DescribeRegistries + // in paginated output. When this parameter is used, DescribeRegistries only + // returns maxResults results in a single page along with a nextToken response + // element. The remaining results of the initial request can be seen by sending + // another DescribeRegistries request with the returned nextToken value. This + // value can be between 1 and 1000. If this parameter isn't used, then + // DescribeRegistries returns up to 100 results and a nextToken value, if + // applicable. MaxResults *int32 - // The nextToken value returned from a previous paginated DescribeRegistries + // The nextToken value that's returned from a previous paginated DescribeRegistries // request where maxResults was used and the results exceeded the value of that // parameter. Pagination continues from the end of the previous results that - // returned the nextToken value. This value is null when there are no more results - // to return. This token should be treated as an opaque identifier that is only - // used to retrieve the next items in a list and not for other programmatic + // returned the nextToken value. If there are no more results to return, this + // value is null . This token should be treated as an opaque identifier that is + // only used to retrieve the next items in a list and not for other programmatic // purposes. NextToken *string @@ -53,15 +58,15 @@ type DescribeRegistriesInput struct { type DescribeRegistriesOutput struct { - // An object containing the details for a public registry. + // An object that contains the details for a public registry. // // This member is required. Registries []types.Registry - // The nextToken value to include in a future DescribeRepositories request. When - // the results of a DescribeRepositories request exceed maxResults, this value can - // be used to retrieve the next page of results. This value is null when there are - // no more results to return. + // The nextToken value to include in a future DescribeRepositories request. If the + // results of a DescribeRepositories request exceed maxResults , you can use this + // value to retrieve the next page of results. If there are no more results, this + // value is null . NextToken *string // Metadata pertaining to the operation's result. @@ -79,6 +84,9 @@ func (c *Client) addOperationDescribeRegistriesMiddlewares(stack *middleware.Sta if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -106,7 +114,7 @@ func (c *Client) addOperationDescribeRegistriesMiddlewares(stack *middleware.Sta if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -115,9 +123,15 @@ func (c *Client) addOperationDescribeRegistriesMiddlewares(stack *middleware.Sta if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDescribeRegistriesResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeRegistries(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -127,6 +141,9 @@ func (c *Client) addOperationDescribeRegistriesMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -141,13 +158,14 @@ var _ DescribeRegistriesAPIClient = (*Client)(nil) // DescribeRegistriesPaginatorOptions is the paginator options for // DescribeRegistries type DescribeRegistriesPaginatorOptions struct { - // The maximum number of repository results returned by DescribeRegistries in - // paginated output. When this parameter is used, DescribeRegistries only returns - // maxResults results in a single page along with a nextToken response element. The - // remaining results of the initial request can be seen by sending another - // DescribeRegistries request with the returned nextToken value. This value can be - // between 1 and 1000. If this parameter is not used, then DescribeRegistries - // returns up to 100 results and a nextToken value, if applicable. + // The maximum number of repository results that's returned by DescribeRegistries + // in paginated output. When this parameter is used, DescribeRegistries only + // returns maxResults results in a single page along with a nextToken response + // element. The remaining results of the initial request can be seen by sending + // another DescribeRegistries request with the returned nextToken value. This + // value can be between 1 and 1000. If this parameter isn't used, then + // DescribeRegistries returns up to 100 results and a nextToken value, if + // applicable. Limit int32 // Set to true if pagination should stop if the service returns a pagination token @@ -235,3 +253,126 @@ func newServiceMetadataMiddleware_opDescribeRegistries(region string) *awsmiddle OperationName: "DescribeRegistries", } } + +type opDescribeRegistriesResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDescribeRegistriesResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDescribeRegistriesResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDescribeRegistriesResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDescribeRegistriesResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRepositories.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRepositories.go index 6f446f513..4185abcc8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRepositories.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRepositories.go @@ -4,15 +4,19 @@ package ecrpublic import ( "context" + "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Describes repositories in a public registry. +// Describes repositories that are in a public registry. func (c *Client) DescribeRepositories(ctx context.Context, params *DescribeRepositoriesInput, optFns ...func(*Options)) (*DescribeRepositoriesOutput, error) { if params == nil { params = &DescribeRepositoriesInput{} @@ -30,29 +34,30 @@ func (c *Client) DescribeRepositories(ctx context.Context, params *DescribeRepos type DescribeRepositoriesInput struct { - // The maximum number of repository results returned by DescribeRepositories in - // paginated output. When this parameter is used, DescribeRepositories only returns - // maxResults results in a single page along with a nextToken response element. The - // remaining results of the initial request can be seen by sending another - // DescribeRepositories request with the returned nextToken value. This value can - // be between 1 and 1000. If this parameter is not used, then DescribeRepositories - // returns up to 100 results and a nextToken value, if applicable. This option - // cannot be used when you specify repositories with repositoryNames. + // The maximum number of repository results that's returned by DescribeRepositories + // in paginated output. When this parameter is used, DescribeRepositories only + // returns maxResults results in a single page along with a nextToken response + // element. You can see the remaining results of the initial request by sending + // another DescribeRepositories request with the returned nextToken value. This + // value can be between 1 and 1000. If this parameter isn't used, then + // DescribeRepositories returns up to 100 results and a nextToken value, if + // applicable. If you specify repositories with repositoryNames , you can't use + // this option. MaxResults *int32 - // The nextToken value returned from a previous paginated DescribeRepositories - // request where maxResults was used and the results exceeded the value of that - // parameter. Pagination continues from the end of the previous results that - // returned the nextToken value. This value is null when there are no more results - // to return. This option cannot be used when you specify repositories with - // repositoryNames. This token should be treated as an opaque identifier that is - // only used to retrieve the next items in a list and not for other programmatic - // purposes. + // The nextToken value that's returned from a previous paginated + // DescribeRepositories request where maxResults was used and the results exceeded + // the value of that parameter. Pagination continues from the end of the previous + // results that returned the nextToken value. If there are no more results to + // return, this value is null . If you specify repositories with repositoryNames , + // you can't use this option. This token should be treated as an opaque identifier + // that is only used to retrieve the next items in a list and not for other + // programmatic purposes. NextToken *string - // The AWS account ID associated with the registry that contains the repositories - // to be described. If you do not specify a registry, the default public registry - // is assumed. + // The Amazon Web Services account ID that's associated with the registry that + // contains the repositories to be described. If you do not specify a registry, the + // default public registry is assumed. RegistryId *string // A list of repositories to describe. If this parameter is omitted, then all @@ -65,9 +70,9 @@ type DescribeRepositoriesInput struct { type DescribeRepositoriesOutput struct { // The nextToken value to include in a future DescribeRepositories request. When - // the results of a DescribeRepositories request exceed maxResults, this value can - // be used to retrieve the next page of results. This value is null when there are - // no more results to return. + // the results of a DescribeRepositories request exceed maxResults , this value can + // be used to retrieve the next page of results. If there are no more results to + // return, this value is null . NextToken *string // A list of repository objects corresponding to valid repositories. @@ -88,6 +93,9 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -115,7 +123,7 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -124,9 +132,15 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDescribeRepositoriesResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeRepositories(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -136,6 +150,9 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -150,14 +167,15 @@ var _ DescribeRepositoriesAPIClient = (*Client)(nil) // DescribeRepositoriesPaginatorOptions is the paginator options for // DescribeRepositories type DescribeRepositoriesPaginatorOptions struct { - // The maximum number of repository results returned by DescribeRepositories in - // paginated output. When this parameter is used, DescribeRepositories only returns - // maxResults results in a single page along with a nextToken response element. The - // remaining results of the initial request can be seen by sending another - // DescribeRepositories request with the returned nextToken value. This value can - // be between 1 and 1000. If this parameter is not used, then DescribeRepositories - // returns up to 100 results and a nextToken value, if applicable. This option - // cannot be used when you specify repositories with repositoryNames. + // The maximum number of repository results that's returned by DescribeRepositories + // in paginated output. When this parameter is used, DescribeRepositories only + // returns maxResults results in a single page along with a nextToken response + // element. You can see the remaining results of the initial request by sending + // another DescribeRepositories request with the returned nextToken value. This + // value can be between 1 and 1000. If this parameter isn't used, then + // DescribeRepositories returns up to 100 results and a nextToken value, if + // applicable. If you specify repositories with repositoryNames , you can't use + // this option. Limit int32 // Set to true if pagination should stop if the service returns a pagination token @@ -245,3 +263,126 @@ func newServiceMetadataMiddleware_opDescribeRepositories(region string) *awsmidd OperationName: "DescribeRepositories", } } + +type opDescribeRepositoriesResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDescribeRepositoriesResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDescribeRepositoriesResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDescribeRepositoriesResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDescribeRepositoriesResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetAuthorizationToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetAuthorizationToken.go index adbe13a0c..c7b8801b5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetAuthorizationToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetAuthorizationToken.go @@ -4,15 +4,20 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Retrieves an authorization token. An authorization token represents your IAM -// authentication credentials and can be used to access any Amazon ECR registry +// authentication credentials. You can use it to access any Amazon ECR registry // that your IAM principal has access to. The authorization token is valid for 12 // hours. This API requires the ecr-public:GetAuthorizationToken and // sts:GetServiceBearerToken permissions. @@ -55,6 +60,9 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -82,7 +90,7 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -91,9 +99,15 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetAuthorizationTokenResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetAuthorizationToken(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -103,6 +117,9 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -114,3 +131,126 @@ func newServiceMetadataMiddleware_opGetAuthorizationToken(region string) *awsmid OperationName: "GetAuthorizationToken", } } + +type opGetAuthorizationTokenResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetAuthorizationTokenResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetAuthorizationTokenResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetAuthorizationTokenResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetAuthorizationTokenResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRegistryCatalogData.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRegistryCatalogData.go index 88cd5b4bc..42758d295 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRegistryCatalogData.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRegistryCatalogData.go @@ -4,9 +4,14 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -53,6 +58,9 @@ func (c *Client) addOperationGetRegistryCatalogDataMiddlewares(stack *middleware if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -80,7 +88,7 @@ func (c *Client) addOperationGetRegistryCatalogDataMiddlewares(stack *middleware if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -89,9 +97,15 @@ func (c *Client) addOperationGetRegistryCatalogDataMiddlewares(stack *middleware if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetRegistryCatalogDataResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRegistryCatalogData(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -101,6 +115,9 @@ func (c *Client) addOperationGetRegistryCatalogDataMiddlewares(stack *middleware if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -112,3 +129,126 @@ func newServiceMetadataMiddleware_opGetRegistryCatalogData(region string) *awsmi OperationName: "GetRegistryCatalogData", } } + +type opGetRegistryCatalogDataResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetRegistryCatalogDataResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetRegistryCatalogDataResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetRegistryCatalogDataResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetRegistryCatalogDataResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryCatalogData.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryCatalogData.go index 5c7173fe3..7e2a74fb5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryCatalogData.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryCatalogData.go @@ -4,9 +4,14 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -35,9 +40,9 @@ type GetRepositoryCatalogDataInput struct { // This member is required. RepositoryName *string - // The AWS account ID associated with the registry that contains the repositories - // to be described. If you do not specify a registry, the default public registry - // is assumed. + // The Amazon Web Services account ID that's associated with the registry that + // contains the repositories to be described. If you do not specify a registry, the + // default public registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -63,6 +68,9 @@ func (c *Client) addOperationGetRepositoryCatalogDataMiddlewares(stack *middlewa if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -90,7 +98,7 @@ func (c *Client) addOperationGetRepositoryCatalogDataMiddlewares(stack *middlewa if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -99,12 +107,18 @@ func (c *Client) addOperationGetRepositoryCatalogDataMiddlewares(stack *middlewa if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetRepositoryCatalogDataResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetRepositoryCatalogDataValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRepositoryCatalogData(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -114,6 +128,9 @@ func (c *Client) addOperationGetRepositoryCatalogDataMiddlewares(stack *middlewa if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -125,3 +142,126 @@ func newServiceMetadataMiddleware_opGetRepositoryCatalogData(region string) *aws OperationName: "GetRepositoryCatalogData", } } + +type opGetRepositoryCatalogDataResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetRepositoryCatalogDataResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetRepositoryCatalogDataResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetRepositoryCatalogDataResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetRepositoryCatalogDataResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryPolicy.go index 80584f924..f104aada5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryPolicy.go @@ -4,8 +4,13 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -33,9 +38,9 @@ type GetRepositoryPolicyInput struct { // This member is required. RepositoryName *string - // The AWS account ID associated with the public registry that contains the - // repository. If you do not specify a registry, the default public registry is - // assumed. + // The Amazon Web Services account ID that's associated with the public registry + // that contains the repository. If you do not specify a registry, the default + // public registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -43,14 +48,14 @@ type GetRepositoryPolicyInput struct { type GetRepositoryPolicyOutput struct { - // The repository policy text associated with the repository. The policy text will - // be in JSON format. + // The repository policy text that's associated with the repository. The policy + // text will be in JSON format. PolicyText *string - // The registry ID associated with the request. + // The registry ID that's associated with the request. RegistryId *string - // The repository name associated with the request. + // The repository name that's associated with the request. RepositoryName *string // Metadata pertaining to the operation's result. @@ -68,6 +73,9 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -95,7 +103,7 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -104,12 +112,18 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetRepositoryPolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetRepositoryPolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRepositoryPolicy(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -119,6 +133,9 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -130,3 +147,126 @@ func newServiceMetadataMiddleware_opGetRepositoryPolicy(region string) *awsmiddl OperationName: "GetRepositoryPolicy", } } + +type opGetRepositoryPolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetRepositoryPolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetRepositoryPolicyResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetRepositoryPolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetRepositoryPolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_InitiateLayerUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_InitiateLayerUpload.go index 1b4576d78..ee562fbad 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_InitiateLayerUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_InitiateLayerUpload.go @@ -4,19 +4,23 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Notifies Amazon ECR that you intend to upload an image layer. When an image is -// pushed, the InitiateLayerUpload API is called once per image layer that has not -// already been uploaded. Whether or not an image layer has been uploaded is -// determined by the BatchCheckLayerAvailability API action. This operation is used -// by the Amazon ECR proxy and is not generally used by customers for pulling and -// pushing images. In most cases, you should use the docker CLI to pull, tag, and -// push images. +// pushed, the InitiateLayerUpload API is called once for each image layer that +// hasn't already been uploaded. Whether an image layer uploads is determined by +// the BatchCheckLayerAvailability API action. This operation is used by the Amazon +// ECR proxy and is not generally used by customers for pulling and pushing images. +// In most cases, you should use the docker CLI to pull, tag, and push images. func (c *Client) InitiateLayerUpload(ctx context.Context, params *InitiateLayerUploadInput, optFns ...func(*Options)) (*InitiateLayerUploadOutput, error) { if params == nil { params = &InitiateLayerUploadInput{} @@ -34,14 +38,14 @@ func (c *Client) InitiateLayerUpload(ctx context.Context, params *InitiateLayerU type InitiateLayerUploadInput struct { - // The name of the repository to which you intend to upload layers. + // The name of the repository that you want to upload layers to. // // This member is required. RepositoryName *string - // The AWS account ID associated with the registry to which you intend to upload - // layers. If you do not specify a registry, the default public registry is - // assumed. + // The Amazon Web Services account ID, or registry alias, that's associated with + // the registry to which you intend to upload layers. If you do not specify a + // registry, the default public registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -71,6 +75,9 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -98,7 +105,7 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -107,12 +114,18 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addInitiateLayerUploadResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpInitiateLayerUploadValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opInitiateLayerUpload(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -122,6 +135,9 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -133,3 +149,126 @@ func newServiceMetadataMiddleware_opInitiateLayerUpload(region string) *awsmiddl OperationName: "InitiateLayerUpload", } } + +type opInitiateLayerUploadResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opInitiateLayerUploadResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opInitiateLayerUploadResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addInitiateLayerUploadResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opInitiateLayerUploadResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_ListTagsForResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_ListTagsForResource.go index 6db006279..34e23ec8c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_ListTagsForResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_ListTagsForResource.go @@ -4,9 +4,14 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -29,8 +34,8 @@ func (c *Client) ListTagsForResource(ctx context.Context, params *ListTagsForRes type ListTagsForResourceInput struct { - // The Amazon Resource Name (ARN) that identifies the resource for which to list - // the tags. Currently, the supported resource is an Amazon ECR Public repository. + // The Amazon Resource Name (ARN) that identifies the resource to list the tags + // for. Currently, the supported resource is an Amazon ECR Public repository. // // This member is required. ResourceArn *string @@ -58,6 +63,9 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -85,7 +93,7 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -94,12 +102,18 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addListTagsForResourceResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpListTagsForResourceValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListTagsForResource(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -109,6 +123,9 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -120,3 +137,126 @@ func newServiceMetadataMiddleware_opListTagsForResource(region string) *awsmiddl OperationName: "ListTagsForResource", } } + +type opListTagsForResourceResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListTagsForResourceResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListTagsForResourceResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListTagsForResourceResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListTagsForResourceResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutImage.go index 3a2cbdbd8..5aa1d530a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutImage.go @@ -4,19 +4,24 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Creates or updates the image manifest and tags associated with an image. When an -// image is pushed and all new image layers have been uploaded, the PutImage API is -// called once to create or update the image manifest and the tags associated with -// the image. This operation is used by the Amazon ECR proxy and is not generally -// used by customers for pulling and pushing images. In most cases, you should use -// the docker CLI to pull, tag, and push images. +// Creates or updates the image manifest and tags that are associated with an +// image. When an image is pushed and all new image layers have been uploaded, the +// PutImage API is called once to create or update the image manifest and the tags +// that are associated with the image. This operation is used by the Amazon ECR +// proxy and is not generally used by customers for pulling and pushing images. In +// most cases, you should use the docker CLI to pull, tag, and push images. func (c *Client) PutImage(ctx context.Context, params *PutImageInput, optFns ...func(*Options)) (*PutImageOutput, error) { if params == nil { params = &PutImageInput{} @@ -34,22 +39,22 @@ func (c *Client) PutImage(ctx context.Context, params *PutImageInput, optFns ... type PutImageInput struct { - // The image manifest corresponding to the image to be uploaded. + // The image manifest that corresponds to the image to be uploaded. // // This member is required. ImageManifest *string - // The name of the repository in which to put the image. + // The name of the repository where the image is put. // // This member is required. RepositoryName *string - // The image digest of the image manifest corresponding to the image. + // The image digest of the image manifest that corresponds to the image. ImageDigest *string - // The media type of the image manifest. If you push an image manifest that does - // not contain the mediaType field, you must specify the imageManifestMediaType in - // the request. + // The media type of the image manifest. If you push an image manifest that + // doesn't contain the mediaType field, you must specify the imageManifestMediaType + // in the request. ImageManifestMediaType *string // The tag to associate with the image. This parameter is required for images that @@ -57,9 +62,9 @@ type PutImageInput struct { // formats. ImageTag *string - // The AWS account ID associated with the public registry that contains the - // repository in which to put the image. If you do not specify a registry, the - // default public registry is assumed. + // The Amazon Web Services account ID, or registry alias, that's associated with + // the public registry that contains the repository where the image is put. If you + // do not specify a registry, the default public registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -85,6 +90,9 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -112,7 +120,7 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -121,12 +129,18 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addPutImageResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutImageValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutImage(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -136,6 +150,9 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -147,3 +164,126 @@ func newServiceMetadataMiddleware_opPutImage(region string) *awsmiddleware.Regis OperationName: "PutImage", } } + +type opPutImageResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutImageResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutImageResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutImageResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutImageResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRegistryCatalogData.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRegistryCatalogData.go index 994364a53..bc2e24c79 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRegistryCatalogData.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRegistryCatalogData.go @@ -4,14 +4,19 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Create or updates the catalog data for a public registry. +// Create or update the catalog data for a public registry. func (c *Client) PutRegistryCatalogData(ctx context.Context, params *PutRegistryCatalogDataInput, optFns ...func(*Options)) (*PutRegistryCatalogDataOutput, error) { if params == nil { params = &PutRegistryCatalogDataInput{} @@ -59,6 +64,9 @@ func (c *Client) addOperationPutRegistryCatalogDataMiddlewares(stack *middleware if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -86,7 +94,7 @@ func (c *Client) addOperationPutRegistryCatalogDataMiddlewares(stack *middleware if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -95,9 +103,15 @@ func (c *Client) addOperationPutRegistryCatalogDataMiddlewares(stack *middleware if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addPutRegistryCatalogDataResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutRegistryCatalogData(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -107,6 +121,9 @@ func (c *Client) addOperationPutRegistryCatalogDataMiddlewares(stack *middleware if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -118,3 +135,126 @@ func newServiceMetadataMiddleware_opPutRegistryCatalogData(region string) *awsmi OperationName: "PutRegistryCatalogData", } } + +type opPutRegistryCatalogDataResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutRegistryCatalogDataResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutRegistryCatalogDataResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutRegistryCatalogDataResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutRegistryCatalogDataResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRepositoryCatalogData.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRepositoryCatalogData.go index 4510287f3..c76c4cf1c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRepositoryCatalogData.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRepositoryCatalogData.go @@ -4,9 +4,14 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -40,8 +45,9 @@ type PutRepositoryCatalogDataInput struct { // This member is required. RepositoryName *string - // The AWS account ID associated with the public registry the repository is in. If - // you do not specify a registry, the default public registry is assumed. + // The Amazon Web Services account ID that's associated with the public registry + // the repository is in. If you do not specify a registry, the default public + // registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -67,6 +73,9 @@ func (c *Client) addOperationPutRepositoryCatalogDataMiddlewares(stack *middlewa if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -94,7 +103,7 @@ func (c *Client) addOperationPutRepositoryCatalogDataMiddlewares(stack *middlewa if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -103,12 +112,18 @@ func (c *Client) addOperationPutRepositoryCatalogDataMiddlewares(stack *middlewa if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addPutRepositoryCatalogDataResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutRepositoryCatalogDataValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutRepositoryCatalogData(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -118,6 +133,9 @@ func (c *Client) addOperationPutRepositoryCatalogDataMiddlewares(stack *middlewa if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -129,3 +147,126 @@ func newServiceMetadataMiddleware_opPutRepositoryCatalogData(region string) *aws OperationName: "PutRepositoryCatalogData", } } + +type opPutRepositoryCatalogDataResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutRepositoryCatalogDataResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutRepositoryCatalogDataResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutRepositoryCatalogDataResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutRepositoryCatalogDataResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_SetRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_SetRepositoryPolicy.go index 46fdd68ad..72a968686 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_SetRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_SetRepositoryPolicy.go @@ -4,15 +4,19 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Applies a repository policy to the specified public repository to control access -// permissions. For more information, see Amazon ECR Repository Policies -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html) +// Applies a repository policy to the specified public repository to control +// access permissions. For more information, see Amazon ECR Repository Policies (https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html) // in the Amazon Elastic Container Registry User Guide. func (c *Client) SetRepositoryPolicy(ctx context.Context, params *SetRepositoryPolicyInput, optFns ...func(*Options)) (*SetRepositoryPolicyOutput, error) { if params == nil { @@ -32,8 +36,7 @@ func (c *Client) SetRepositoryPolicy(ctx context.Context, params *SetRepositoryP type SetRepositoryPolicyInput struct { // The JSON repository policy text to apply to the repository. For more - // information, see Amazon ECR Repository Policies - // (https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policy-examples.html) + // information, see Amazon ECR Repository Policies (https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policy-examples.html) // in the Amazon Elastic Container Registry User Guide. // // This member is required. @@ -44,14 +47,14 @@ type SetRepositoryPolicyInput struct { // This member is required. RepositoryName *string - // If the policy you are attempting to set on a repository policy would prevent you + // If the policy that you want to set on a repository policy would prevent you // from setting another policy in the future, you must force the - // SetRepositoryPolicy operation. This is intended to prevent accidental repository - // lock outs. + // SetRepositoryPolicy operation. This prevents accidental repository lockouts. Force bool - // The AWS account ID associated with the registry that contains the repository. If - // you do not specify a registry, the default public registry is assumed. + // The Amazon Web Services account ID that's associated with the registry that + // contains the repository. If you do not specify a registry, the default public + // registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -59,13 +62,13 @@ type SetRepositoryPolicyInput struct { type SetRepositoryPolicyOutput struct { - // The JSON repository policy text applied to the repository. + // The JSON repository policy text that's applied to the repository. PolicyText *string - // The registry ID associated with the request. + // The registry ID that's associated with the request. RegistryId *string - // The repository name associated with the request. + // The repository name that's associated with the request. RepositoryName *string // Metadata pertaining to the operation's result. @@ -83,6 +86,9 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -110,7 +116,7 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -119,12 +125,18 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetRepositoryPolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpSetRepositoryPolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opSetRepositoryPolicy(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -134,6 +146,9 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -145,3 +160,126 @@ func newServiceMetadataMiddleware_opSetRepositoryPolicy(region string) *awsmiddl OperationName: "SetRepositoryPolicy", } } + +type opSetRepositoryPolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opSetRepositoryPolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opSetRepositoryPolicyResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addSetRepositoryPolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opSetRepositoryPolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_TagResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_TagResource.go index 0e7044006..94fe4edf1 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_TagResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_TagResource.go @@ -4,17 +4,22 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Associates the specified tags to a resource with the specified resourceArn. If -// existing tags on a resource are not specified in the request parameters, they -// are not changed. When a resource is deleted, the tags associated with that -// resource are deleted as well. +// Associates the specified tags to a resource with the specified resourceArn . If +// existing tags on a resource aren't specified in the request parameters, they +// aren't changed. When a resource is deleted, the tags associated with that +// resource are also deleted. func (c *Client) TagResource(ctx context.Context, params *TagResourceInput, optFns ...func(*Options)) (*TagResourceOutput, error) { if params == nil { params = &TagResourceInput{} @@ -32,8 +37,8 @@ func (c *Client) TagResource(ctx context.Context, params *TagResourceInput, optF type TagResourceInput struct { - // The Amazon Resource Name (ARN) of the resource to which to add tags. Currently, - // the supported resource is an Amazon ECR Public repository. + // The Amazon Resource Name (ARN) of the resource to add tags to. Currently, the + // supported resource is an Amazon ECR Public repository. // // This member is required. ResourceArn *string @@ -64,6 +69,9 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -91,7 +99,7 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -100,12 +108,18 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addTagResourceResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpTagResourceValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opTagResource(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -115,6 +129,9 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -126,3 +143,126 @@ func newServiceMetadataMiddleware_opTagResource(region string) *awsmiddleware.Re OperationName: "TagResource", } } + +type opTagResourceResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opTagResourceResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opTagResourceResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addTagResourceResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opTagResourceResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UntagResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UntagResource.go index 8f042d4c8..bff2b1c3a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UntagResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UntagResource.go @@ -4,8 +4,13 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -28,8 +33,8 @@ func (c *Client) UntagResource(ctx context.Context, params *UntagResourceInput, type UntagResourceInput struct { - // The Amazon Resource Name (ARN) of the resource from which to delete tags. - // Currently, the supported resource is an Amazon ECR Public repository. + // The Amazon Resource Name (ARN) of the resource to delete tags from. Currently, + // the supported resource is an Amazon ECR Public repository. // // This member is required. ResourceArn *string @@ -58,6 +63,9 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -85,7 +93,7 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -94,12 +102,18 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addUntagResourceResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpUntagResourceValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUntagResource(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -109,6 +123,9 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -120,3 +137,126 @@ func newServiceMetadataMiddleware_opUntagResource(region string) *awsmiddleware. OperationName: "UntagResource", } } + +type opUntagResourceResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opUntagResourceResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opUntagResourceResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addUntagResourceResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opUntagResourceResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UploadLayerPart.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UploadLayerPart.go index ce3fa0a4a..dadc5f39c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UploadLayerPart.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UploadLayerPart.go @@ -4,18 +4,23 @@ package ecrpublic import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Uploads an image layer part to Amazon ECR. When an image is pushed, each new // image layer is uploaded in parts. The maximum size of each image layer part can -// be 20971520 bytes (or about 20MB). The UploadLayerPart API is called once per -// each new image layer part. This operation is used by the Amazon ECR proxy and is -// not generally used by customers for pulling and pushing images. In most cases, -// you should use the docker CLI to pull, tag, and push images. +// be 20971520 bytes (about 20MB). The UploadLayerPart API is called once for each +// new image layer part. This operation is used by the Amazon ECR proxy and is not +// generally used by customers for pulling and pushing images. In most cases, you +// should use the docker CLI to pull, tag, and push images. func (c *Client) UploadLayerPart(ctx context.Context, params *UploadLayerPartInput, optFns ...func(*Options)) (*UploadLayerPartOutput, error) { if params == nil { params = &UploadLayerPartInput{} @@ -48,7 +53,7 @@ type UploadLayerPartInput struct { // This member is required. PartLastByte *int64 - // The name of the repository to which you are uploading layer parts. + // The name of the repository that you're uploading layer parts to. // // This member is required. RepositoryName *string @@ -59,8 +64,9 @@ type UploadLayerPartInput struct { // This member is required. UploadId *string - // The AWS account ID associated with the registry to which you are uploading layer - // parts. If you do not specify a registry, the default public registry is assumed. + // The Amazon Web Services account ID, or registry alias, that's associated with + // the registry that you're uploading layer parts to. If you do not specify a + // registry, the default public registry is assumed. RegistryId *string noSmithyDocumentSerde @@ -68,16 +74,16 @@ type UploadLayerPartInput struct { type UploadLayerPartOutput struct { - // The integer value of the last byte received in the request. + // The integer value of the last byte that's received in the request. LastByteReceived *int64 - // The registry ID associated with the request. + // The registry ID that's associated with the request. RegistryId *string - // The repository name associated with the request. + // The repository name that's associated with the request. RepositoryName *string - // The upload ID associated with the request. + // The upload ID that's associated with the request. UploadId *string // Metadata pertaining to the operation's result. @@ -95,6 +101,9 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -122,7 +131,7 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -131,12 +140,18 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addUploadLayerPartResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpUploadLayerPartValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUploadLayerPart(options.Region), middleware.Before); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } @@ -146,6 +161,9 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -157,3 +175,126 @@ func newServiceMetadataMiddleware_opUploadLayerPart(region string) *awsmiddlewar OperationName: "UploadLayerPart", } } + +type opUploadLayerPartResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opUploadLayerPartResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opUploadLayerPartResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "ecr-public" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "ecr-public" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("ecr-public") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addUploadLayerPartResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opUploadLayerPartResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/deserializers.go index 2a9ac6204..0ef759a1c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/deserializers.go @@ -86,9 +86,9 @@ func awsAwsjson11_deserializeOpErrorBatchCheckLayerAvailability(response *smithy errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -97,7 +97,7 @@ func awsAwsjson11_deserializeOpErrorBatchCheckLayerAvailability(response *smithy body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -109,8 +109,8 @@ func awsAwsjson11_deserializeOpErrorBatchCheckLayerAvailability(response *smithy } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -129,6 +129,9 @@ func awsAwsjson11_deserializeOpErrorBatchCheckLayerAvailability(response *smithy case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -206,9 +209,9 @@ func awsAwsjson11_deserializeOpErrorBatchDeleteImage(response *smithyhttp.Respon errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -217,7 +220,7 @@ func awsAwsjson11_deserializeOpErrorBatchDeleteImage(response *smithyhttp.Respon body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -229,8 +232,8 @@ func awsAwsjson11_deserializeOpErrorBatchDeleteImage(response *smithyhttp.Respon } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -246,6 +249,9 @@ func awsAwsjson11_deserializeOpErrorBatchDeleteImage(response *smithyhttp.Respon case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -323,9 +329,9 @@ func awsAwsjson11_deserializeOpErrorCompleteLayerUpload(response *smithyhttp.Res errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -334,7 +340,7 @@ func awsAwsjson11_deserializeOpErrorCompleteLayerUpload(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -346,8 +352,8 @@ func awsAwsjson11_deserializeOpErrorCompleteLayerUpload(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -461,9 +467,9 @@ func awsAwsjson11_deserializeOpErrorCreateRepository(response *smithyhttp.Respon errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -472,7 +478,7 @@ func awsAwsjson11_deserializeOpErrorCreateRepository(response *smithyhttp.Respon body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -484,8 +490,8 @@ func awsAwsjson11_deserializeOpErrorCreateRepository(response *smithyhttp.Respon } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -510,6 +516,9 @@ func awsAwsjson11_deserializeOpErrorCreateRepository(response *smithyhttp.Respon case strings.EqualFold("TooManyTagsException", errorCode): return awsAwsjson11_deserializeErrorTooManyTagsException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -587,9 +596,9 @@ func awsAwsjson11_deserializeOpErrorDeleteRepository(response *smithyhttp.Respon errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -598,7 +607,7 @@ func awsAwsjson11_deserializeOpErrorDeleteRepository(response *smithyhttp.Respon body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -610,8 +619,8 @@ func awsAwsjson11_deserializeOpErrorDeleteRepository(response *smithyhttp.Respon } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -630,6 +639,9 @@ func awsAwsjson11_deserializeOpErrorDeleteRepository(response *smithyhttp.Respon case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -707,9 +719,9 @@ func awsAwsjson11_deserializeOpErrorDeleteRepositoryPolicy(response *smithyhttp. errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -718,7 +730,7 @@ func awsAwsjson11_deserializeOpErrorDeleteRepositoryPolicy(response *smithyhttp. body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -730,8 +742,8 @@ func awsAwsjson11_deserializeOpErrorDeleteRepositoryPolicy(response *smithyhttp. } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -750,6 +762,9 @@ func awsAwsjson11_deserializeOpErrorDeleteRepositoryPolicy(response *smithyhttp. case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -827,9 +842,9 @@ func awsAwsjson11_deserializeOpErrorDescribeImages(response *smithyhttp.Response errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -838,7 +853,7 @@ func awsAwsjson11_deserializeOpErrorDescribeImages(response *smithyhttp.Response body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -850,8 +865,8 @@ func awsAwsjson11_deserializeOpErrorDescribeImages(response *smithyhttp.Response } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -870,6 +885,9 @@ func awsAwsjson11_deserializeOpErrorDescribeImages(response *smithyhttp.Response case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -947,9 +965,9 @@ func awsAwsjson11_deserializeOpErrorDescribeImageTags(response *smithyhttp.Respo errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -958,7 +976,7 @@ func awsAwsjson11_deserializeOpErrorDescribeImageTags(response *smithyhttp.Respo body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -970,8 +988,8 @@ func awsAwsjson11_deserializeOpErrorDescribeImageTags(response *smithyhttp.Respo } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -987,6 +1005,9 @@ func awsAwsjson11_deserializeOpErrorDescribeImageTags(response *smithyhttp.Respo case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -1064,9 +1085,9 @@ func awsAwsjson11_deserializeOpErrorDescribeRegistries(response *smithyhttp.Resp errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -1075,7 +1096,7 @@ func awsAwsjson11_deserializeOpErrorDescribeRegistries(response *smithyhttp.Resp body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1087,8 +1108,8 @@ func awsAwsjson11_deserializeOpErrorDescribeRegistries(response *smithyhttp.Resp } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -1181,9 +1202,9 @@ func awsAwsjson11_deserializeOpErrorDescribeRepositories(response *smithyhttp.Re errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -1192,7 +1213,7 @@ func awsAwsjson11_deserializeOpErrorDescribeRepositories(response *smithyhttp.Re body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1204,8 +1225,8 @@ func awsAwsjson11_deserializeOpErrorDescribeRepositories(response *smithyhttp.Re } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -1221,6 +1242,9 @@ func awsAwsjson11_deserializeOpErrorDescribeRepositories(response *smithyhttp.Re case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -1298,9 +1322,9 @@ func awsAwsjson11_deserializeOpErrorGetAuthorizationToken(response *smithyhttp.R errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -1309,7 +1333,7 @@ func awsAwsjson11_deserializeOpErrorGetAuthorizationToken(response *smithyhttp.R body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1321,8 +1345,8 @@ func awsAwsjson11_deserializeOpErrorGetAuthorizationToken(response *smithyhttp.R } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -1335,6 +1359,9 @@ func awsAwsjson11_deserializeOpErrorGetAuthorizationToken(response *smithyhttp.R case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -1412,9 +1439,9 @@ func awsAwsjson11_deserializeOpErrorGetRegistryCatalogData(response *smithyhttp. errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -1423,7 +1450,7 @@ func awsAwsjson11_deserializeOpErrorGetRegistryCatalogData(response *smithyhttp. body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1435,8 +1462,8 @@ func awsAwsjson11_deserializeOpErrorGetRegistryCatalogData(response *smithyhttp. } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -1526,9 +1553,9 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryCatalogData(response *smithyhtt errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -1537,7 +1564,7 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryCatalogData(response *smithyhtt body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1549,8 +1576,8 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryCatalogData(response *smithyhtt } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -1560,12 +1587,18 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryCatalogData(response *smithyhtt case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) + case strings.EqualFold("RepositoryCatalogDataNotFoundException", errorCode): + return awsAwsjson11_deserializeErrorRepositoryCatalogDataNotFoundException(response, errorBody) + case strings.EqualFold("RepositoryNotFoundException", errorCode): return awsAwsjson11_deserializeErrorRepositoryNotFoundException(response, errorBody) case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -1643,9 +1676,9 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryPolicy(response *smithyhttp.Res errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -1654,7 +1687,7 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryPolicy(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1666,8 +1699,8 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryPolicy(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -1686,6 +1719,9 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryPolicy(response *smithyhttp.Res case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -1763,9 +1799,9 @@ func awsAwsjson11_deserializeOpErrorInitiateLayerUpload(response *smithyhttp.Res errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -1774,7 +1810,7 @@ func awsAwsjson11_deserializeOpErrorInitiateLayerUpload(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1786,8 +1822,8 @@ func awsAwsjson11_deserializeOpErrorInitiateLayerUpload(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -1886,9 +1922,9 @@ func awsAwsjson11_deserializeOpErrorListTagsForResource(response *smithyhttp.Res errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -1897,7 +1933,7 @@ func awsAwsjson11_deserializeOpErrorListTagsForResource(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1909,8 +1945,8 @@ func awsAwsjson11_deserializeOpErrorListTagsForResource(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -1926,6 +1962,9 @@ func awsAwsjson11_deserializeOpErrorListTagsForResource(response *smithyhttp.Res case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -2003,9 +2042,9 @@ func awsAwsjson11_deserializeOpErrorPutImage(response *smithyhttp.Response, meta errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -2014,7 +2053,7 @@ func awsAwsjson11_deserializeOpErrorPutImage(response *smithyhttp.Response, meta body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2026,8 +2065,8 @@ func awsAwsjson11_deserializeOpErrorPutImage(response *smithyhttp.Response, meta } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -2144,9 +2183,9 @@ func awsAwsjson11_deserializeOpErrorPutRegistryCatalogData(response *smithyhttp. errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -2155,7 +2194,7 @@ func awsAwsjson11_deserializeOpErrorPutRegistryCatalogData(response *smithyhttp. body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2167,8 +2206,8 @@ func awsAwsjson11_deserializeOpErrorPutRegistryCatalogData(response *smithyhttp. } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -2261,9 +2300,9 @@ func awsAwsjson11_deserializeOpErrorPutRepositoryCatalogData(response *smithyhtt errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -2272,7 +2311,7 @@ func awsAwsjson11_deserializeOpErrorPutRepositoryCatalogData(response *smithyhtt body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2284,8 +2323,8 @@ func awsAwsjson11_deserializeOpErrorPutRepositoryCatalogData(response *smithyhtt } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -2301,6 +2340,9 @@ func awsAwsjson11_deserializeOpErrorPutRepositoryCatalogData(response *smithyhtt case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -2378,9 +2420,9 @@ func awsAwsjson11_deserializeOpErrorSetRepositoryPolicy(response *smithyhttp.Res errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -2389,7 +2431,7 @@ func awsAwsjson11_deserializeOpErrorSetRepositoryPolicy(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2401,8 +2443,8 @@ func awsAwsjson11_deserializeOpErrorSetRepositoryPolicy(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -2418,6 +2460,9 @@ func awsAwsjson11_deserializeOpErrorSetRepositoryPolicy(response *smithyhttp.Res case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -2495,9 +2540,9 @@ func awsAwsjson11_deserializeOpErrorTagResource(response *smithyhttp.Response, m errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -2506,7 +2551,7 @@ func awsAwsjson11_deserializeOpErrorTagResource(response *smithyhttp.Response, m body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2518,8 +2563,8 @@ func awsAwsjson11_deserializeOpErrorTagResource(response *smithyhttp.Response, m } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -2541,6 +2586,9 @@ func awsAwsjson11_deserializeOpErrorTagResource(response *smithyhttp.Response, m case strings.EqualFold("TooManyTagsException", errorCode): return awsAwsjson11_deserializeErrorTooManyTagsException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -2618,9 +2666,9 @@ func awsAwsjson11_deserializeOpErrorUntagResource(response *smithyhttp.Response, errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -2629,7 +2677,7 @@ func awsAwsjson11_deserializeOpErrorUntagResource(response *smithyhttp.Response, body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2641,8 +2689,8 @@ func awsAwsjson11_deserializeOpErrorUntagResource(response *smithyhttp.Response, } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -2664,6 +2712,9 @@ func awsAwsjson11_deserializeOpErrorUntagResource(response *smithyhttp.Response, case strings.EqualFold("TooManyTagsException", errorCode): return awsAwsjson11_deserializeErrorTooManyTagsException(response, errorBody) + case strings.EqualFold("UnsupportedCommandException", errorCode): + return awsAwsjson11_deserializeErrorUnsupportedCommandException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -2741,9 +2792,9 @@ func awsAwsjson11_deserializeOpErrorUploadLayerPart(response *smithyhttp.Respons errorCode := "UnknownError" errorMessage := errorCode - code := response.Header.Get("X-Amzn-ErrorType") - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) } var buff [1024]byte @@ -2752,7 +2803,7 @@ func awsAwsjson11_deserializeOpErrorUploadLayerPart(response *smithyhttp.Respons body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - code, message, err := restjson.GetErrorInfo(decoder) + jsonCode, message, err := restjson.GetErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2764,8 +2815,8 @@ func awsAwsjson11_deserializeOpErrorUploadLayerPart(response *smithyhttp.Respons } errorBody.Seek(0, io.SeekStart) - if len(code) != 0 { - errorCode = restjson.SanitizeErrorCode(code) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) } if len(message) != 0 { errorMessage = message @@ -3366,6 +3417,41 @@ func awsAwsjson11_deserializeErrorRepositoryAlreadyExistsException(response *smi return output } +func awsAwsjson11_deserializeErrorRepositoryCatalogDataNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + 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 + } + + output := &types.RepositoryCatalogDataNotFoundException{} + err := awsAwsjson11_deserializeDocumentRepositoryCatalogDataNotFoundException(&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 awsAwsjson11_deserializeErrorRepositoryNotEmptyException(response *smithyhttp.Response, errorBody *bytes.Reader) error { var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -5637,6 +5723,46 @@ func awsAwsjson11_deserializeDocumentRepositoryCatalogData(v **types.RepositoryC return nil } +func awsAwsjson11_deserializeDocumentRepositoryCatalogDataNotFoundException(v **types.RepositoryCatalogDataNotFoundException, 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.RepositoryCatalogDataNotFoundException + if *v == nil { + sv = &types.RepositoryCatalogDataNotFoundException{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "message": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected ExceptionMessage to be of type string, got %T instead", value) + } + sv.Message = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + func awsAwsjson11_deserializeDocumentRepositoryList(v *[]types.Repository, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/doc.go index a17297a09..8706038fd 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/doc.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/doc.go @@ -4,12 +4,12 @@ // Amazon Elastic Container Registry Public. // // Amazon Elastic Container Registry Public Amazon Elastic Container Registry -// (Amazon ECR) is a managed container image registry service. Amazon ECR provides -// both public and private registries to host your container images. You can use -// the familiar Docker CLI, or their preferred client, to push, pull, and manage +// Public (Amazon ECR Public) is a managed container image registry service. Amazon +// ECR provides both public and private registries to host your container images. +// You can use the Docker CLI or your preferred client to push, pull, and manage // images. Amazon ECR provides a secure, scalable, and reliable registry for your // Docker or Open Container Initiative (OCI) images. Amazon ECR supports public // repositories with this API. For information about the Amazon ECR API for private -// repositories, see Amazon Elastic Container Registry API Reference -// (https://docs.aws.amazon.com/AmazonECR/latest/APIReference/Welcome.html). +// repositories, see Amazon Elastic Container Registry API Reference (https://docs.aws.amazon.com/AmazonECR/latest/APIReference/Welcome.html) +// . package ecrpublic diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/endpoints.go index 071eca69c..b2ed73070 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/endpoints.go @@ -8,9 +8,13 @@ import ( "fmt" "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/endpoints/awsrulesfn" internalendpoints "github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" smithyhttp "github.com/aws/smithy-go/transport/http" + "net/http" "net/url" "strings" ) @@ -39,13 +43,6 @@ func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointRe return fn(region, options) } -func resolveDefaultEndpointConfiguration(o *Options) { - if o.EndpointResolver != nil { - return - } - o.EndpointResolver = NewDefaultEndpointResolver() -} - // 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 @@ -79,6 +76,10 @@ func (*ResolveEndpoint) ID() string { 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) @@ -94,6 +95,11 @@ func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.Ser 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) } @@ -129,27 +135,10 @@ func removeResolveEndpointMiddleware(stack *middleware.Stack) error { type wrappedEndpointResolver struct { awsResolver aws.EndpointResolverWithOptions - resolver EndpointResolver } func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - if w.awsResolver == nil { - goto fallback - } - endpoint, err = w.awsResolver.ResolveEndpoint(ServiceID, region, options) - if err == nil { - return endpoint, nil - } - - if nf := (&aws.EndpointNotFoundError{}); !errors.As(err, &nf) { - return endpoint, err - } - -fallback: - if w.resolver == nil { - return endpoint, fmt.Errorf("default endpoint resolver provided was nil") - } - return w.resolver.ResolveEndpoint(region, options) + return w.awsResolver.ResolveEndpoint(ServiceID, region, options) } type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error) @@ -160,12 +149,13 @@ func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, opti var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil) -// withEndpointResolver returns an EndpointResolver that first delegates endpoint resolution to the awsResolver. -// If awsResolver returns aws.EndpointNotFoundError error, the resolver will use the the provided -// fallbackResolver for resolution. +// 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. // -// fallbackResolver must not be nil -func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions, fallbackResolver EndpointResolver) EndpointResolver { +// 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 { @@ -176,7 +166,6 @@ func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptio return &wrappedEndpointResolver{ awsResolver: resolver, - resolver: fallbackResolver, } } @@ -198,3 +187,294 @@ func finalizeClientEndpointResolverOptions(options *Options) { } } + +func resolveEndpointResolverV2(options *Options) { + if options.EndpointResolverV2 == nil { + options.EndpointResolverV2 = NewDefaultEndpointResolverV2() + } +} + +// Utility function to aid with translating pseudo-regions to classical regions +// with the appropriate setting indicated by the pseudo-region +func mapPseudoRegion(pr string) (region string, fips aws.FIPSEndpointState) { + const fipsInfix = "-fips-" + const fipsPrefix = "fips-" + const fipsSuffix = "-fips" + + if strings.Contains(pr, fipsInfix) || + strings.Contains(pr, fipsPrefix) || + strings.Contains(pr, fipsSuffix) { + region = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll( + pr, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "") + fips = aws.FIPSEndpointStateEnabled + } else { + region = pr + } + + return region, fips +} + +// builtInParameterResolver is the interface responsible for resolving BuiltIn +// values during the sourcing of EndpointParameters +type builtInParameterResolver interface { + ResolveBuiltIns(*EndpointParameters) error +} + +// builtInResolver resolves modeled BuiltIn values using only the members defined +// below. +type builtInResolver struct { + // The AWS region used to dispatch the request. + Region string + + // Sourced BuiltIn value in a historical enabled or disabled state. + UseDualStack aws.DualStackEndpointState + + // Sourced BuiltIn value in a historical enabled or disabled state. + UseFIPS aws.FIPSEndpointState + + // Base endpoint that can potentially be modified during Endpoint resolution. + Endpoint *string +} + +// Invoked at runtime to resolve BuiltIn Values. Only resolution code specific to +// each BuiltIn value is generated. +func (b *builtInResolver) ResolveBuiltIns(params *EndpointParameters) error { + + region, _ := mapPseudoRegion(b.Region) + if len(region) == 0 { + return fmt.Errorf("Could not resolve AWS::Region") + } else { + params.Region = aws.String(region) + } + if b.UseDualStack == aws.DualStackEndpointStateEnabled { + params.UseDualStack = aws.Bool(true) + } else { + params.UseDualStack = aws.Bool(false) + } + if b.UseFIPS == aws.FIPSEndpointStateEnabled { + params.UseFIPS = aws.Bool(true) + } else { + params.UseFIPS = aws.Bool(false) + } + params.Endpoint = b.Endpoint + return 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 +} + +// 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 +} + +// 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://api.ecr-public-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 { + uriString := func() string { + var out strings.Builder + out.WriteString("https://api.ecr-public-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://api.ecr-public.") + 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://api.ecr-public.") + 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") +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/generated.json index a60655a86..067ae4319 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/generated.json @@ -3,7 +3,8 @@ "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" + "github.com/aws/smithy-go": "v1.4.0", + "github.com/google/go-cmp": "v0.5.4" }, "files": [ "api_client.go", @@ -34,6 +35,7 @@ "deserializers.go", "doc.go", "endpoints.go", + "endpoints_test.go", "generated.json", "internal/endpoints/endpoints.go", "internal/endpoints/endpoints_test.go", diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/go_module_metadata.go index 45b1d3dac..10b100d2f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/go_module_metadata.go @@ -3,4 +3,4 @@ package ecrpublic // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.12.0" +const goModuleVersion = "1.18.2" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints/endpoints.go index 356bda290..7f1222959 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints/endpoints.go @@ -89,13 +89,17 @@ var partitionRegexp = struct { 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)\\-\\w+\\-\\d+$"), + Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il)\\-\\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+$"), } @@ -134,6 +138,24 @@ var defaultPartitions = endpoints.Partitions{ }, RegionRegex: partitionRegexp.Aws, IsRegionalized: true, + Endpoints: endpoints.Endpoints{ + endpoints.EndpointKey{ + Region: "us-east-1", + }: endpoints.Endpoint{ + Hostname: "api.ecr-public.us-east-1.amazonaws.com", + CredentialScope: endpoints.CredentialScope{ + Region: "us-east-1", + }, + }, + endpoints.EndpointKey{ + Region: "us-west-2", + }: endpoints.Endpoint{ + Hostname: "api.ecr-public.us-west-2.amazonaws.com", + CredentialScope: endpoints.CredentialScope{ + Region: "us-west-2", + }, + }, + }, }, { ID: "aws-cn", @@ -212,6 +234,48 @@ var defaultPartitions = endpoints.Partitions{ RegionRegex: partitionRegexp.AwsIsoB, IsRegionalized: true, }, + { + ID: "aws-iso-e", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "api.ecr-public-fips.{region}.cloud.adc-e.uk", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "api.ecr-public.{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: "api.ecr-public-fips.{region}.csp.hci.ic.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "api.ecr-public.{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{ diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/types/errors.go index 485ac0c1d..24f4d43c7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/types/errors.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/types/errors.go @@ -7,10 +7,12 @@ import ( smithy "github.com/aws/smithy-go" ) -// The specified layer upload does not contain any layer parts. +// The specified layer upload doesn't contain any layer parts. type EmptyUploadException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -23,7 +25,12 @@ func (e *EmptyUploadException) ErrorMessage() string { } return *e.Message } -func (e *EmptyUploadException) ErrorCode() string { return "EmptyUploadException" } +func (e *EmptyUploadException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "EmptyUploadException" + } + return *e.ErrorCodeOverride +} func (e *EmptyUploadException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } // The specified image has already been pushed, and there were no changes to the @@ -31,6 +38,8 @@ func (e *EmptyUploadException) ErrorFault() smithy.ErrorFault { return smithy.Fa type ImageAlreadyExistsException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -43,14 +52,21 @@ func (e *ImageAlreadyExistsException) ErrorMessage() string { } return *e.Message } -func (e *ImageAlreadyExistsException) ErrorCode() string { return "ImageAlreadyExistsException" } +func (e *ImageAlreadyExistsException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "ImageAlreadyExistsException" + } + return *e.ErrorCodeOverride +} func (e *ImageAlreadyExistsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The specified image digest does not match the digest that Amazon ECR calculated +// The specified image digest doesn't match the digest that Amazon ECR calculated // for the image. type ImageDigestDoesNotMatchException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -64,14 +80,19 @@ func (e *ImageDigestDoesNotMatchException) ErrorMessage() string { return *e.Message } func (e *ImageDigestDoesNotMatchException) ErrorCode() string { - return "ImageDigestDoesNotMatchException" + if e == nil || e.ErrorCodeOverride == nil { + return "ImageDigestDoesNotMatchException" + } + return *e.ErrorCodeOverride } func (e *ImageDigestDoesNotMatchException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The image requested does not exist in the specified repository. +// The image requested doesn't exist in the specified repository. type ImageNotFoundException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -84,7 +105,12 @@ func (e *ImageNotFoundException) ErrorMessage() string { } return *e.Message } -func (e *ImageNotFoundException) ErrorCode() string { return "ImageNotFoundException" } +func (e *ImageNotFoundException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "ImageNotFoundException" + } + return *e.ErrorCodeOverride +} func (e *ImageNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } // The specified image is tagged with a tag that already exists. The repository is @@ -92,6 +118,8 @@ func (e *ImageNotFoundException) ErrorFault() smithy.ErrorFault { return smithy. type ImageTagAlreadyExistsException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -104,14 +132,21 @@ func (e *ImageTagAlreadyExistsException) ErrorMessage() string { } return *e.Message } -func (e *ImageTagAlreadyExistsException) ErrorCode() string { return "ImageTagAlreadyExistsException" } +func (e *ImageTagAlreadyExistsException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "ImageTagAlreadyExistsException" + } + return *e.ErrorCodeOverride +} func (e *ImageTagAlreadyExistsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The layer digest calculation performed by Amazon ECR upon receipt of the image -// layer does not match the digest specified. +// The layer digest calculation performed by Amazon ECR when the image layer +// doesn't match the digest specified. type InvalidLayerException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -124,14 +159,21 @@ func (e *InvalidLayerException) ErrorMessage() string { } return *e.Message } -func (e *InvalidLayerException) ErrorCode() string { return "InvalidLayerException" } +func (e *InvalidLayerException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "InvalidLayerException" + } + return *e.ErrorCodeOverride +} func (e *InvalidLayerException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The layer part size is not valid, or the first byte specified is not consecutive +// The layer part size isn't valid, or the first byte specified isn't consecutive // to the last byte of a previous layer part upload. type InvalidLayerPartException struct { Message *string + ErrorCodeOverride *string + RegistryId *string RepositoryName *string UploadId *string @@ -149,7 +191,12 @@ func (e *InvalidLayerPartException) ErrorMessage() string { } return *e.Message } -func (e *InvalidLayerPartException) ErrorCode() string { return "InvalidLayerPartException" } +func (e *InvalidLayerPartException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "InvalidLayerPartException" + } + return *e.ErrorCodeOverride +} func (e *InvalidLayerPartException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } // The specified parameter is invalid. Review the available parameters for the API @@ -157,6 +204,8 @@ func (e *InvalidLayerPartException) ErrorFault() smithy.ErrorFault { return smit type InvalidParameterException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -169,7 +218,12 @@ func (e *InvalidParameterException) ErrorMessage() string { } return *e.Message } -func (e *InvalidParameterException) ErrorCode() string { return "InvalidParameterException" } +func (e *InvalidParameterException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "InvalidParameterException" + } + return *e.ErrorCodeOverride +} func (e *InvalidParameterException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } // An invalid parameter has been specified. Tag keys can have a maximum character @@ -178,6 +232,8 @@ func (e *InvalidParameterException) ErrorFault() smithy.ErrorFault { return smit type InvalidTagParameterException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -190,13 +246,20 @@ func (e *InvalidTagParameterException) ErrorMessage() string { } return *e.Message } -func (e *InvalidTagParameterException) ErrorCode() string { return "InvalidTagParameterException" } +func (e *InvalidTagParameterException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "InvalidTagParameterException" + } + return *e.ErrorCodeOverride +} func (e *InvalidTagParameterException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } // The image layer already exists in the associated repository. type LayerAlreadyExistsException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -209,13 +272,20 @@ func (e *LayerAlreadyExistsException) ErrorMessage() string { } return *e.Message } -func (e *LayerAlreadyExistsException) ErrorCode() string { return "LayerAlreadyExistsException" } +func (e *LayerAlreadyExistsException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "LayerAlreadyExistsException" + } + return *e.ErrorCodeOverride +} func (e *LayerAlreadyExistsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } // Layer parts must be at least 5 MiB in size. type LayerPartTooSmallException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -228,14 +298,21 @@ func (e *LayerPartTooSmallException) ErrorMessage() string { } return *e.Message } -func (e *LayerPartTooSmallException) ErrorCode() string { return "LayerPartTooSmallException" } +func (e *LayerPartTooSmallException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "LayerPartTooSmallException" + } + return *e.ErrorCodeOverride +} func (e *LayerPartTooSmallException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The specified layers could not be found, or the specified layer is not valid for +// The specified layers can't be found, or the specified layer isn't valid for // this repository. type LayersNotFoundException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -248,16 +325,22 @@ func (e *LayersNotFoundException) ErrorMessage() string { } return *e.Message } -func (e *LayersNotFoundException) ErrorCode() string { return "LayersNotFoundException" } +func (e *LayersNotFoundException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "LayersNotFoundException" + } + return *e.ErrorCodeOverride +} func (e *LayersNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The operation did not succeed because it would have exceeded a service limit for -// your account. For more information, see Amazon ECR Service Quotas -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service-quotas.html) in -// the Amazon Elastic Container Registry User Guide. +// The operation didn't succeed because it would have exceeded a service limit for +// your account. For more information, see Amazon ECR Service Quotas (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service-quotas.html) +// in the Amazon Elastic Container Registry User Guide. type LimitExceededException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -270,13 +353,20 @@ func (e *LimitExceededException) ErrorMessage() string { } return *e.Message } -func (e *LimitExceededException) ErrorCode() string { return "LimitExceededException" } +func (e *LimitExceededException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "LimitExceededException" + } + return *e.ErrorCodeOverride +} func (e *LimitExceededException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The manifest list is referencing an image that does not exist. +// The manifest list is referencing an image that doesn't exist. type ReferencedImagesNotFoundException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -290,14 +380,19 @@ func (e *ReferencedImagesNotFoundException) ErrorMessage() string { return *e.Message } func (e *ReferencedImagesNotFoundException) ErrorCode() string { - return "ReferencedImagesNotFoundException" + if e == nil || e.ErrorCodeOverride == nil { + return "ReferencedImagesNotFoundException" + } + return *e.ErrorCodeOverride } func (e *ReferencedImagesNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The registry does not exist. +// The registry doesn't exist. type RegistryNotFoundException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -310,13 +405,20 @@ func (e *RegistryNotFoundException) ErrorMessage() string { } return *e.Message } -func (e *RegistryNotFoundException) ErrorCode() string { return "RegistryNotFoundException" } +func (e *RegistryNotFoundException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "RegistryNotFoundException" + } + return *e.ErrorCodeOverride +} func (e *RegistryNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } // The specified repository already exists in the specified registry. type RepositoryAlreadyExistsException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -330,15 +432,48 @@ func (e *RepositoryAlreadyExistsException) ErrorMessage() string { return *e.Message } func (e *RepositoryAlreadyExistsException) ErrorCode() string { - return "RepositoryAlreadyExistsException" + if e == nil || e.ErrorCodeOverride == nil { + return "RepositoryAlreadyExistsException" + } + return *e.ErrorCodeOverride } func (e *RepositoryAlreadyExistsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } +// The repository catalog data doesn't exist. +type RepositoryCatalogDataNotFoundException struct { + Message *string + + ErrorCodeOverride *string + + noSmithyDocumentSerde +} + +func (e *RepositoryCatalogDataNotFoundException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *RepositoryCatalogDataNotFoundException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *RepositoryCatalogDataNotFoundException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "RepositoryCatalogDataNotFoundException" + } + return *e.ErrorCodeOverride +} +func (e *RepositoryCatalogDataNotFoundException) ErrorFault() smithy.ErrorFault { + return smithy.FaultClient +} + // The specified repository contains images. To delete a repository that contains // images, you must force the deletion with the force parameter. type RepositoryNotEmptyException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -351,15 +486,21 @@ func (e *RepositoryNotEmptyException) ErrorMessage() string { } return *e.Message } -func (e *RepositoryNotEmptyException) ErrorCode() string { return "RepositoryNotEmptyException" } +func (e *RepositoryNotEmptyException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "RepositoryNotEmptyException" + } + return *e.ErrorCodeOverride +} func (e *RepositoryNotEmptyException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The specified repository could not be found. Check the spelling of the specified -// repository and ensure that you are performing operations on the correct -// registry. +// The specified repository can't be found. Check the spelling of the specified +// repository and ensure that you're performing operations on the correct registry. type RepositoryNotFoundException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -372,14 +513,21 @@ func (e *RepositoryNotFoundException) ErrorMessage() string { } return *e.Message } -func (e *RepositoryNotFoundException) ErrorCode() string { return "RepositoryNotFoundException" } +func (e *RepositoryNotFoundException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "RepositoryNotFoundException" + } + return *e.ErrorCodeOverride +} func (e *RepositoryNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The specified repository and registry combination does not have an associated +// The specified repository and registry combination doesn't have an associated // repository policy. type RepositoryPolicyNotFoundException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -393,7 +541,10 @@ func (e *RepositoryPolicyNotFoundException) ErrorMessage() string { return *e.Message } func (e *RepositoryPolicyNotFoundException) ErrorCode() string { - return "RepositoryPolicyNotFoundException" + if e == nil || e.ErrorCodeOverride == nil { + return "RepositoryPolicyNotFoundException" + } + return *e.ErrorCodeOverride } func (e *RepositoryPolicyNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } @@ -401,6 +552,8 @@ func (e *RepositoryPolicyNotFoundException) ErrorFault() smithy.ErrorFault { ret type ServerException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -413,14 +566,21 @@ func (e *ServerException) ErrorMessage() string { } return *e.Message } -func (e *ServerException) ErrorCode() string { return "ServerException" } +func (e *ServerException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "ServerException" + } + return *e.ErrorCodeOverride +} func (e *ServerException) ErrorFault() smithy.ErrorFault { return smithy.FaultServer } -// The list of tags on the repository is over the limit. The maximum number of tags -// that can be applied to a repository is 50. +// The list of tags on the repository is over the limit. The maximum number of +// tags that can be applied to a repository is 50. type TooManyTagsException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -433,13 +593,20 @@ func (e *TooManyTagsException) ErrorMessage() string { } return *e.Message } -func (e *TooManyTagsException) ErrorCode() string { return "TooManyTagsException" } +func (e *TooManyTagsException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "TooManyTagsException" + } + return *e.ErrorCodeOverride +} func (e *TooManyTagsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The action is not supported in this Region. +// The action isn't supported in this Region. type UnsupportedCommandException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -452,14 +619,21 @@ func (e *UnsupportedCommandException) ErrorMessage() string { } return *e.Message } -func (e *UnsupportedCommandException) ErrorCode() string { return "UnsupportedCommandException" } +func (e *UnsupportedCommandException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "UnsupportedCommandException" + } + return *e.ErrorCodeOverride +} func (e *UnsupportedCommandException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The upload could not be found, or the specified upload ID is not valid for this +// The upload can't be found, or the specified upload ID isn't valid for this // repository. type UploadNotFoundException struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -472,5 +646,10 @@ func (e *UploadNotFoundException) ErrorMessage() string { } return *e.Message } -func (e *UploadNotFoundException) ErrorCode() string { return "UploadNotFoundException" } +func (e *UploadNotFoundException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "UploadNotFoundException" + } + return *e.ErrorCodeOverride +} func (e *UploadNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/types/types.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/types/types.go index 731ea603d..b24a2f4e4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/types/types.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/types/types.go @@ -10,9 +10,9 @@ import ( // An authorization token data object that corresponds to a public registry. type AuthorizationData struct { - // A base64-encoded string that contains authorization data for a public Amazon ECR - // registry. When the string is decoded, it is presented in the format - // user:password for public registry authentication using docker login. + // A base64-encoded string that contains authorization data for a public Amazon + // ECR registry. When the string is decoded, it's presented in the format + // user:password for public registry authentication using docker login . AuthorizationToken *string // The Unix time in seconds and milliseconds when the authorization token expires. @@ -22,28 +22,29 @@ type AuthorizationData struct { noSmithyDocumentSerde } -// An object representing an Amazon ECR image. +// An object that represents an Amazon ECR image. type Image struct { - // An object containing the image tag and image digest associated with an image. + // An object that contains the image tag and image digest associated with an image. ImageId *ImageIdentifier - // The image manifest associated with the image. + // The image manifest that's associated with the image. ImageManifest *string // The manifest media type of the image. ImageManifestMediaType *string - // The AWS account ID associated with the registry containing the image. + // The Amazon Web Services account ID that's associated with the registry + // containing the image. RegistryId *string - // The name of the repository associated with the image. + // The name of the repository that's associated with the image. RepositoryName *string noSmithyDocumentSerde } -// An object that describes an image returned by a DescribeImages operation. +// An object that describes an image that's returned by a DescribeImages operation. type ImageDetail struct { // The artifact media type of the image. @@ -55,41 +56,41 @@ type ImageDetail struct { // The media type of the image manifest. ImageManifestMediaType *string - // The date and time, expressed in standard JavaScript date format, at which the - // current image was pushed to the repository. + // The date and time, expressed in standard JavaScript date format, that the + // current image was pushed to the repository at. ImagePushedAt *time.Time // The size, in bytes, of the image in the repository. If the image is a manifest - // list, this will be the max size of all manifests in the list. Beginning with - // Docker version 1.9, the Docker client compresses image layers before pushing - // them to a V2 Docker registry. The output of the docker images command shows the - // uncompressed image size, so it may return a larger image size than the image - // sizes returned by DescribeImages. + // list, this is the max size of all manifests in the list. Beginning with Docker + // version 1.9, the Docker client compresses image layers before pushing them to a + // V2 Docker registry. The output of the docker images command shows the + // uncompressed image size, so it might return a larger image size than the image + // sizes that are returned by DescribeImages . ImageSizeInBytes *int64 - // The list of tags associated with this image. + // The list of tags that's associated with this image. ImageTags []string - // The AWS account ID associated with the public registry to which this image - // belongs. + // The Amazon Web Services account ID that's associated with the public registry + // where this image belongs. RegistryId *string - // The name of the repository to which this image belongs. + // The name of the repository where this image belongs. RepositoryName *string noSmithyDocumentSerde } -// An object representing an Amazon ECR image failure. +// An object that represents an Amazon ECR image failure. type ImageFailure struct { - // The code associated with the failure. + // The code that's associated with the failure. FailureCode ImageFailureCode // The reason for the failure. FailureReason *string - // The image ID associated with the failure. + // The image ID that's associated with the failure. ImageId *ImageIdentifier noSmithyDocumentSerde @@ -101,28 +102,28 @@ type ImageIdentifier struct { // The sha256 digest of the image manifest. ImageDigest *string - // The tag used for the image. + // The tag that's used for the image. ImageTag *string noSmithyDocumentSerde } -// An object representing the image tag details for an image. +// An object that represents the image tag details for an image. type ImageTagDetail struct { - // The time stamp indicating when the image tag was created. + // The time stamp that indicates when the image tag was created. CreatedAt *time.Time // An object that describes the details of an image. ImageDetail *ReferencedImageDetail - // The tag associated with the image. + // The tag that's associated with the image. ImageTag *string noSmithyDocumentSerde } -// An object representing an Amazon ECR image layer. +// An object that represents an Amazon ECR image layer. type Layer struct { // The availability status of the image layer. @@ -136,29 +137,29 @@ type Layer struct { // The media type of the layer, such as // application/vnd.docker.image.rootfs.diff.tar.gzip or - // application/vnd.oci.image.layer.v1.tar+gzip. + // application/vnd.oci.image.layer.v1.tar+gzip . MediaType *string noSmithyDocumentSerde } -// An object representing an Amazon ECR image layer failure. +// An object that represents an Amazon ECR image layer failure. type LayerFailure struct { - // The failure code associated with the failure. + // The failure code that's associated with the failure. FailureCode LayerFailureCode // The reason for the failure. FailureReason *string - // The layer digest associated with the failure. + // The layer digest that's associated with the failure. LayerDigest *string noSmithyDocumentSerde } -// An object that describes the image tag details returned by a DescribeImageTags -// action. +// An object that describes the image tag details that are returned by a +// DescribeImageTags action. type ReferencedImageDetail struct { // The artifact media type of the image. @@ -170,16 +171,16 @@ type ReferencedImageDetail struct { // The media type of the image manifest. ImageManifestMediaType *string - // The date and time, expressed in standard JavaScript date format, at which the - // current image tag was pushed to the repository. + // The date and time, expressed in standard JavaScript date format, which the + // current image tag was pushed to the repository at. ImagePushedAt *time.Time // The size, in bytes, of the image in the repository. If the image is a manifest - // list, this will be the max size of all manifests in the list. Beginning with - // Docker version 1.9, the Docker client compresses image layers before pushing - // them to a V2 Docker registry. The output of the docker images command shows the - // uncompressed image size, so it may return a larger image size than the image - // sizes returned by DescribeImages. + // list, this is the max size of all manifests in the list. Beginning with Docker + // version 1.9, the Docker client compresses image layers before pushing them to a + // V2 Docker registry. The output of the docker images command shows the + // uncompressed image size, so it might return a larger image size than the image + // sizes that are returned by DescribeImages . ImageSizeInBytes *int64 noSmithyDocumentSerde @@ -188,7 +189,7 @@ type ReferencedImageDetail struct { // The details of a public registry. type Registry struct { - // An array of objects representing the aliases for a public registry. + // An array of objects that represents the aliases for a public registry. // // This member is required. Aliases []RegistryAlias @@ -198,8 +199,8 @@ type Registry struct { // This member is required. RegistryArn *string - // The AWS account ID associated with the registry. If you do not specify a - // registry, the default public registry is assumed. + // The Amazon Web Services account ID that's associated with the registry. If you + // do not specify a registry, the default public registry is assumed. // // This member is required. RegistryId *string @@ -210,9 +211,9 @@ type Registry struct { // This member is required. RegistryUri *string - // Whether the account is verified. This indicates whether the account is an AWS - // Marketplace vendor. If an account is verified, each public repository will - // received a verified account badge on the Amazon ECR Public Gallery. + // Indicates whether the account is a verified Amazon Web Services Marketplace + // vendor. If an account is verified, each public repository receives a verified + // account badge on the Amazon ECR Public Gallery. // // This member is required. Verified *bool @@ -221,14 +222,13 @@ type Registry struct { } // An object representing the aliases for a public registry. A public registry is -// given an alias upon creation but a custom alias can be set using the Amazon ECR -// console. For more information, see Registries -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/Registries.html) in the -// Amazon Elastic Container Registry User Guide. +// given an alias when it's created. However, a custom alias can be set using the +// Amazon ECR console. For more information, see Registries (https://docs.aws.amazon.com/AmazonECR/latest/userguide/Registries.html) +// in the Amazon Elastic Container Registry User Guide. type RegistryAlias struct { - // Whether or not the registry alias is the default alias for the registry. When - // the first public repository is created, your public registry is assigned a + // Indicates whether the registry alias is the default alias for the registry. + // When the first public repository is created, your public registry is assigned a // default registry alias. // // This member is required. @@ -239,10 +239,10 @@ type RegistryAlias struct { // This member is required. Name *string - // Whether or not the registry alias is the primary alias for the registry. If + // Indicates whether the registry alias is the primary alias for the registry. If // true, the alias is the primary registry alias and is displayed in both the // repository URL and the image URI used in the docker pull commands on the Amazon - // ECR Public Gallery. A registry alias that is not the primary registry alias can + // ECR Public Gallery. A registry alias that isn't the primary registry alias can // be used in the repository URI in a docker pull command. // // This member is required. @@ -273,14 +273,14 @@ type Repository struct { // The date and time, in JavaScript date format, when the repository was created. CreatedAt *time.Time - // The AWS account ID associated with the public registry that contains the - // repository. + // The Amazon Web Services account ID that's associated with the public registry + // that contains the repository. RegistryId *string // The Amazon Resource Name (ARN) that identifies the repository. The ARN contains - // the arn:aws:ecr namespace, followed by the region of the repository, AWS account - // ID of the repository owner, repository namespace, and repository name. For - // example, arn:aws:ecr:region:012345678910:repository/test. + // the arn:aws:ecr namespace, followed by the region of the repository, Amazon Web + // Services account ID of the repository owner, repository namespace, and + // repository name. For example, arn:aws:ecr:region:012345678910:repository/test . RepositoryArn *string // The name of the repository. @@ -297,27 +297,28 @@ type Repository struct { // ECR Public Gallery. type RepositoryCatalogData struct { - // The longform description of the contents of the repository. This text appears in - // the repository details on the Amazon ECR Public Gallery. + // The longform description of the contents of the repository. This text appears + // in the repository details on the Amazon ECR Public Gallery. AboutText *string // The architecture tags that are associated with the repository. Only supported // operating system tags appear publicly in the Amazon ECR Public Gallery. For more - // information, see RepositoryCatalogDataInput. + // information, see RepositoryCatalogDataInput . Architectures []string // The short description of the repository. Description *string - // The URL containing the logo associated with the repository. + // The URL that contains the logo that's associated with the repository. LogoUrl *string - // Whether or not the repository is certified by AWS Marketplace. + // Indicates whether the repository is certified by Amazon Web Services + // Marketplace. MarketplaceCertified *bool // The operating system tags that are associated with the repository. Only // supported operating system tags appear publicly in the Amazon ECR Public - // Gallery. For more information, see RepositoryCatalogDataInput. + // Gallery. For more information, see RepositoryCatalogDataInput . OperatingSystems []string // The longform usage details of the contents of the repository. The usage text @@ -327,56 +328,46 @@ type RepositoryCatalogData struct { noSmithyDocumentSerde } -// An object containing the catalog data for a repository. This data is publicly -// visible in the Amazon ECR Public Gallery. +// An object that contains the catalog data for a repository. This data is +// publicly visible in the Amazon ECR Public Gallery. type RepositoryCatalogDataInput struct { - // A detailed description of the contents of the repository. It is publicly visible + // A detailed description of the contents of the repository. It's publicly visible // in the Amazon ECR Public Gallery. The text must be in markdown format. AboutText *string // The system architecture that the images in the repository are compatible with. - // On the Amazon ECR Public Gallery, the following supported architectures will - // appear as badges on the repository and are used as search filters. - // - // * Linux - // - // * - // Windows - // - // If an unsupported tag is added to your repository catalog data, it will - // be associated with the repository and can be retrieved using the API but will - // not be discoverable in the Amazon ECR Public Gallery. + // On the Amazon ECR Public Gallery, the following supported architectures appear + // as badges on the repository and are used as search filters. If an unsupported + // tag is added to your repository catalog data, it's associated with the + // repository and can be retrieved using the API but isn't discoverable in the + // Amazon ECR Public Gallery. + // - ARM + // - ARM 64 + // - x86 + // - x86-64 Architectures []string - // A short description of the contents of the repository. This text appears in both - // the image details and also when searching for repositories on the Amazon ECR - // Public Gallery. + // A short description of the contents of the repository. This text appears in + // both the image details and also when searching for repositories on the Amazon + // ECR Public Gallery. Description *string - // The base64-encoded repository logo payload. The repository logo is only publicly - // visible in the Amazon ECR Public Gallery for verified accounts. + // The base64-encoded repository logo payload. The repository logo is only + // publicly visible in the Amazon ECR Public Gallery for verified accounts. LogoImageBlob []byte // The operating systems that the images in the repository are compatible with. On - // the Amazon ECR Public Gallery, the following supported operating systems will - // appear as badges on the repository and are used as search filters. - // - // * ARM - // - // * ARM - // 64 - // - // * x86 - // - // * x86-64 - // - // If an unsupported tag is added to your repository catalog - // data, it will be associated with the repository and can be retrieved using the - // API but will not be discoverable in the Amazon ECR Public Gallery. + // the Amazon ECR Public Gallery, the following supported operating systems appear + // as badges on the repository and are used as search filters. If an unsupported + // tag is added to your repository catalog data, it's associated with the + // repository and can be retrieved using the API but isn't discoverable in the + // Amazon ECR Public Gallery. + // - Linux + // - Windows OperatingSystems []string - // Detailed information on how to use the contents of the repository. It is + // Detailed information about how to use the contents of the repository. It's // publicly visible in the Amazon ECR Public Gallery. The usage text provides // context, support information, and additional usage details for users of the // repository. The text must be in markdown format. @@ -386,9 +377,9 @@ type RepositoryCatalogDataInput struct { } // The metadata that you apply to a resource to help you categorize and organize -// them. Each tag consists of a key and an optional value, both of which you -// define. Tag keys can have a maximum character length of 128 characters, and tag -// values can have a maximum length of 256 characters. +// them. Each tag consists of a key and an optional value. You define both. Tag +// keys can have a maximum character length of 128 characters, and tag values can +// have a maximum length of 256 characters. type Tag struct { // One part of a key-value pair that make up a tag. A key is a general label that 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 index dec755d42..289c55c23 100644 --- 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 @@ -1,3 +1,23 @@ +# 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. 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 index 04ff9fb79..187ef12b3 100644 --- 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 @@ -3,4 +3,4 @@ package acceptencoding // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.9.9" +const goModuleVersion = "1.9.14" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/checksum/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/checksum/CHANGELOG.md index 90efb0987..cf2e59dd4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/checksum/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/checksum/CHANGELOG.md @@ -1,3 +1,75 @@ +# v1.1.36 (2023-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.35 (2023-08-18) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.34 (2023-08-17) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.33 (2023-08-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.32 (2023-07-31) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.31 (2023-07-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.30 (2023-07-13) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.29 (2023-06-13) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.28 (2023-04-24) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.27 (2023-04-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.26 (2023-03-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.25 (2023-03-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.24 (2023-02-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.23 (2023-02-03) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.22 (2022-12-15) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.21 (2022-12-02) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.20 (2022-10-24) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.1.19 (2022-10-21) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.1.18 (2022-09-20) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/checksum/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/checksum/go_module_metadata.go index c95af9a11..479bff9cb 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/checksum/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/checksum/go_module_metadata.go @@ -3,4 +3,4 @@ package checksum // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.1.18" +const goModuleVersion = "1.1.36" 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 index c60858a10..318955895 100644 --- 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 @@ -1,3 +1,39 @@ +# 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 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 index ea2621e47..1d73a0cde 100644 --- 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 @@ -3,4 +3,4 @@ package presignedurl // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.9.28" +const goModuleVersion = "1.9.37" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/CHANGELOG.md index ccc3c7479..a7676224d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/CHANGELOG.md @@ -1,3 +1,77 @@ +# v1.15.4 (2023-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.15.3 (2023-08-18) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.15.2 (2023-08-17) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.15.1 (2023-08-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# 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.5 (2023-07-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.14.4 (2023-07-13) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.14.3 (2023-06-13) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.14.2 (2023-04-24) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.14.1 (2023-04-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.14.0 (2023-03-21) + +* **Feature**: port v1 sdk 100-continue http header customization for s3 PutObject/UploadPart request and enable user config +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.24 (2023-03-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.23 (2023-02-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.22 (2023-02-03) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.21 (2022-12-15) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.20 (2022-12-02) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.19 (2022-10-24) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.18 (2022-10-21) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.13.17 (2022-09-20) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/arn/arn_member.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/arn/arn_member.go new file mode 100644 index 000000000..9a3258e15 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/arn/arn_member.go @@ -0,0 +1,32 @@ +package arn + +import "fmt" + +// arnable is implemented by the relevant S3/S3Control +// operations which have members that may need ARN +// processing. +type arnable interface { + SetARNMember(string) error + GetARNMember() (*string, bool) +} + +// GetARNField would be called during middleware execution +// to retrieve a member value that is an ARN in need of +// processing. +func GetARNField(input interface{}) (*string, bool) { + v, ok := input.(arnable) + if !ok { + return nil, false + } + return v.GetARNMember() +} + +// SetARNField would called during middleware exeuction +// to set a member value that required ARN processing. +func SetARNField(input interface{}, v string) error { + params, ok := input.(arnable) + if !ok { + return fmt.Errorf("Params does not contain arn field member") + } + return params.SetARNMember(v) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/config/config.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/config/config.go index 8926e5970..b5d31f5c5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/config/config.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/config/config.go @@ -7,6 +7,11 @@ type UseARNRegionProvider interface { GetS3UseARNRegion(ctx context.Context) (value bool, found bool, err error) } +// DisableMultiRegionAccessPointsProvider is an interface for retrieving external configuration value for DisableMultiRegionAccessPoints +type DisableMultiRegionAccessPointsProvider interface { + GetS3DisableMultiRegionAccessPoints(ctx context.Context) (value bool, found bool, err error) +} + // ResolveUseARNRegion extracts the first instance of a UseARNRegion 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 ResolveUseARNRegion(ctx context.Context, configs []interface{}) (value bool, found bool, err error) { @@ -20,3 +25,17 @@ func ResolveUseARNRegion(ctx context.Context, configs []interface{}) (value bool } return } + +// ResolveDisableMultiRegionAccessPoints extracts the first instance of a DisableMultiRegionAccessPoints 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 ResolveDisableMultiRegionAccessPoints(ctx context.Context, configs []interface{}) (value bool, found bool, err error) { + for _, cfg := range configs { + if p, ok := cfg.(DisableMultiRegionAccessPointsProvider); ok { + value, found, err = p.GetS3DisableMultiRegionAccessPoints(ctx) + if err != nil || found { + break + } + } + } + return +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/go_module_metadata.go index 3ebafc356..283fe42a0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/go_module_metadata.go @@ -3,4 +3,4 @@ package s3shared // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.13.17" +const goModuleVersion = "1.15.4" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/s3100continue.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/s3100continue.go new file mode 100644 index 000000000..0f43ec0d4 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/s3shared/s3100continue.go @@ -0,0 +1,54 @@ +package s3shared + +import ( + "context" + "fmt" + "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" +) + +const s3100ContinueID = "S3100Continue" +const default100ContinueThresholdBytes int64 = 1024 * 1024 * 2 + +// Add100Continue add middleware, which adds {Expect: 100-continue} header for s3 client HTTP PUT request larger than 2MB +// or with unknown size streaming bodies, during operation builder step +func Add100Continue(stack *middleware.Stack, continueHeaderThresholdBytes int64) error { + return stack.Build.Add(&s3100Continue{ + continueHeaderThresholdBytes: continueHeaderThresholdBytes, + }, middleware.After) +} + +type s3100Continue struct { + continueHeaderThresholdBytes int64 +} + +// ID returns the middleware identifier +func (m *s3100Continue) ID() string { + return s3100ContinueID +} + +func (m *s3100Continue) HandleBuild( + ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler, +) ( + out middleware.BuildOutput, metadata middleware.Metadata, err error, +) { + sizeLimit := default100ContinueThresholdBytes + switch { + case m.continueHeaderThresholdBytes == -1: + return next.HandleBuild(ctx, in) + case m.continueHeaderThresholdBytes > 0: + sizeLimit = m.continueHeaderThresholdBytes + default: + } + + req, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, fmt.Errorf("unknown request type %T", req) + } + + if req.ContentLength == -1 || (req.ContentLength == 0 && req.Body != nil) || req.ContentLength >= sizeLimit { + req.Header.Set("Expect", "100-continue") + } + + return next.HandleBuild(ctx, in) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/CHANGELOG.md index d81bbdb88..608814d4c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/CHANGELOG.md @@ -1,3 +1,155 @@ +# v1.40.0 (2023-09-26) + +* **Feature**: This release adds a new field COMPLETED to the ReplicationStatus Enum. You can now use this field to validate the replication status of S3 objects using the AWS SDK. + +# v1.39.0 (2023-09-20) + +* **Feature**: Fix an issue where the SDK can fail to unmarshall response due to NumberFormatException + +# v1.38.5 (2023-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.4 (2023-08-18) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.3 (2023-08-17) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.2 (2023-08-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.1 (2023-08-01) + +* No change notes available for this release. + +# v1.38.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.37.1 (2023-07-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.37.0 (2023-07-13) + +* **Feature**: S3 Inventory now supports Object Access Control List and Object Owner as available object metadata fields in inventory reports. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.36.0 (2023-06-28) + +* **Feature**: The S3 LISTObjects, ListObjectsV2 and ListObjectVersions API now supports a new optional header x-amz-optional-object-attributes. If header contains RestoreStatus as the value, then S3 will include Glacier restore status i.e. isRestoreInProgress and RestoreExpiryDate in List response. + +# v1.35.0 (2023-06-16) + +* **Feature**: This release adds SDK support for request-payer request header and request-charged response header in the "GetBucketAccelerateConfiguration", "ListMultipartUploads", "ListObjects", "ListObjectsV2" and "ListObjectVersions" S3 APIs. + +# v1.34.1 (2023-06-15) + +* No change notes available for this release. + +# v1.34.0 (2023-06-13) + +* **Feature**: Integrate double encryption feature to SDKs. +* **Bug Fix**: Fix HeadObject to return types.Nound when an object does not exist. Fixes [2084](https://github.com/aws/aws-sdk-go-v2/issues/2084) +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.1 (2023-05-04) + +* **Documentation**: Documentation updates for Amazon S3 + +# v1.33.0 (2023-04-24) + +* **Feature**: added custom paginators for listMultipartUploads and ListObjectVersions +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.0 (2023-04-19) + +* **Feature**: Provides support for "Snow" Storage class. + +# v1.31.3 (2023-04-10) + +* No change notes available for this release. + +# v1.31.2 (2023-04-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.1 (2023-03-31) + +* **Documentation**: Documentation updates for Amazon S3 + +# v1.31.0 (2023-03-21) + +* **Feature**: port v1 sdk 100-continue http header customization for s3 PutObject/UploadPart request and enable user config +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.30.6 (2023-03-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.30.5 (2023-02-22) + +* **Bug Fix**: Prevent nil pointer dereference when retrieving error codes. + +# v1.30.4 (2023-02-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.30.3 (2023-02-14) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.30.2 (2023-02-03) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.30.1 (2023-01-23) + +* No change notes available for this release. + +# v1.30.0 (2023-01-05) + +* **Feature**: Add `ErrorCodeOverride` field to all error structs (aws/smithy-go#401). + +# v1.29.6 (2022-12-15) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.29.5 (2022-12-02) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.29.4 (2022-11-22) + +* No change notes available for this release. + +# v1.29.3 (2022-11-16) + +* No change notes available for this release. + +# v1.29.2 (2022-11-10) + +* No change notes available for this release. + +# v1.29.1 (2022-10-24) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.29.0 (2022-10-21) + +* **Feature**: S3 on Outposts launches support for automatic bucket-style alias. You can use the automatic access point alias instead of an access point ARN for any object-level operation in an Outposts bucket. +* **Bug Fix**: The SDK client has been updated to utilize the `aws.IsCredentialsProvider` function for determining if `aws.AnonymousCredentials` has been configured for the `CredentialProvider`. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.28.0 (2022-10-19) + +* **Feature**: Updates internal logic for constructing API endpoints. We have added rule-based endpoints and internal model parameters. + # v1.27.11 (2022-09-20) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_client.go index 790cc4380..1ddcba2b2 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_client.go @@ -32,8 +32,8 @@ import ( const ServiceID = "S3" const ServiceAPIVersion = "2006-03-01" -// Client provides the API client to make operations call for Amazon Simple Storage -// Service. +// Client provides the API client to make operations call for Amazon Simple +// Storage Service. type Client struct { options Options } @@ -54,20 +54,18 @@ func New(options Options, optFns ...func(*Options)) *Client { resolveHTTPSignerV4(&options) - resolveDefaultEndpointConfiguration(&options) - resolveHTTPSignerV4a(&options) for _, fn := range optFns { fn(&options) } - resolveCredentialProvider(&options) - client := &Client{ options: options, } + resolveCredentialProvider(&options) + return client } @@ -77,9 +75,22 @@ type Options struct { // 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 threshold ContentLength in bytes for HTTP PUT request to receive {Expect: + // 100-continue} header. Setting to -1 will disable adding the Expect header to + // requests; setting to 0 will set the threshold to default 2MB + ContinueHeaderThresholdBytes int64 + // The credentials object to use when signing requests. Credentials aws.CredentialsProvider @@ -94,8 +105,18 @@ type Options struct { 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. This should be used over + // the deprecated EndpointResolver + EndpointResolverV2 EndpointResolverV2 + // Signature Version 4 (SigV4) Signer HTTPSignerV4 HTTPSignerV4 @@ -130,7 +151,7 @@ type Options struct { Retryer aws.Retryer // The RuntimeEnvironment configuration, only populated if the DefaultsMode is set - // to DefaultsModeAuto and is initialized using config.LoadDefaultConfig. You + // 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 @@ -154,8 +175,8 @@ type Options struct { UseDualstack bool // Allows you to enable the client to use path-style addressing, i.e., - // https://s3.amazonaws.com/BUCKET/KEY. By default, the S3 client will use virtual - // hosted bucket addressing when possible(https://BUCKET.s3.amazonaws.com/KEY). + // https://s3.amazonaws.com/BUCKET/KEY . By default, the S3 client will use virtual + // hosted bucket addressing when possible( https://BUCKET.s3.amazonaws.com/KEY ). UsePathStyle bool // Signature Version 4a (SigV4a) Signer @@ -180,14 +201,25 @@ func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { } } -// WithEndpointResolver returns a functional option for setting the Client's -// EndpointResolver option. +// 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 + } +} + type HTTPClient interface { Do(*http.Request) (*http.Response, error) } @@ -204,6 +236,8 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf ctx = middleware.ClearStackValues(ctx) stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) options := c.options.Copy() + resolveEndpointResolverV2(&options) + for _, fn := range optFns { fn(&options) } @@ -242,6 +276,30 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf 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 @@ -279,12 +337,14 @@ func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { APIOptions: cfg.APIOptions, Logger: cfg.Logger, ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) resolveAWSRetryMode(cfg, &opts) resolveAWSEndpointResolver(cfg, &opts) resolveUseARNRegion(cfg, &opts) + resolveDisableMultiRegionAccessPoints(cfg, &opts) resolveUseDualStackEndpoint(cfg, &opts) resolveUseFIPSEndpoint(cfg, &opts) return New(opts, optFns...) @@ -390,11 +450,19 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil { return } - o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions, NewDefaultEndpointResolver()) + o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) } -func addClientUserAgent(stack *middleware.Stack) error { - return awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "s3", goModuleVersion)(stack) +func addClientUserAgent(stack *middleware.Stack, options Options) error { + if err := awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "s3", goModuleVersion)(stack); err != nil { + return err + } + + if len(options.AppID) > 0 { + return awsmiddleware.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID)(stack) + } + + return nil } func addHTTPSignerV4Middleware(stack *middleware.Stack, o Options) error { @@ -448,6 +516,21 @@ func resolveUseARNRegion(cfg aws.Config, o *Options) error { return nil } +// resolves DisableMultiRegionAccessPoints S3 configuration +func resolveDisableMultiRegionAccessPoints(cfg aws.Config, o *Options) error { + if len(cfg.ConfigSources) == 0 { + return nil + } + value, found, err := s3sharedconfig.ResolveDisableMultiRegionAccessPoints(context.Background(), cfg.ConfigSources) + if err != nil { + return err + } + if found { + o.DisableMultiRegionAccessPoints = value + } + return nil +} + // resolves dual-stack endpoint configuration func resolveUseDualStackEndpoint(cfg aws.Config, o *Options) error { if len(cfg.ConfigSources) == 0 { @@ -487,8 +570,7 @@ func resolveCredentialProvider(o *Options) { return } - switch o.Credentials.(type) { - case aws.AnonymousCredentials, *aws.AnonymousCredentials: + if aws.IsCredentialsProvider(o.Credentials, (*aws.AnonymousCredentials)(nil)) { return } @@ -531,8 +613,12 @@ func addMetadataRetrieverMiddleware(stack *middleware.Stack) error { return s3shared.AddMetadataRetrieverMiddleware(stack) } -// ComputedInputChecksumsMetadata provides information about the algorithms used to -// compute the checksum(s) of the input payload. +func add100Continue(stack *middleware.Stack, options Options) error { + return s3shared.Add100Continue(stack, options.ContinueHeaderThresholdBytes) +} + +// ComputedInputChecksumsMetadata provides information about the algorithms used +// to compute the checksum(s) of the input payload. type ComputedInputChecksumsMetadata struct { // ComputedChecksums is a map of algorithm name to checksum value of the computed // input payload's checksums. @@ -552,8 +638,8 @@ func GetComputedInputChecksumsMetadata(m middleware.Metadata) (ComputedInputChec } -// ChecksumValidationMetadata contains metadata such as the checksum algorithm used -// for data integrity validation. +// ChecksumValidationMetadata contains metadata such as the checksum algorithm +// used for data integrity validation. type ChecksumValidationMetadata struct { // AlgorithmsUsed is the set of the checksum algorithms used to validate the // response payload. The response payload must be completely read in order for the @@ -562,10 +648,10 @@ type ChecksumValidationMetadata struct { AlgorithmsUsed []string } -// GetChecksumValidationMetadata returns the set of algorithms that will be used to -// validate the response payload with. The response payload must be completely read -// in order for the checksum validation to be performed. An error is returned by -// the operation output's response io.ReadCloser if the computed checksums are +// GetChecksumValidationMetadata returns the set of algorithms that will be used +// to validate the response payload with. The response payload must be completely +// read in order for the checksum validation to be performed. An error is returned +// by the operation output's response io.ReadCloser if the computed checksums are // invalid. Returns false if no checksum algorithm used metadata was found. func GetChecksumValidationMetadata(m middleware.Metadata) (ChecksumValidationMetadata, bool) { values, ok := internalChecksum.GetOutputValidationAlgorithmsUsed(m) @@ -592,8 +678,8 @@ func disableAcceptEncodingGzip(stack *middleware.Stack) error { return acceptencodingcust.AddAcceptEncodingGzip(stack, acceptencodingcust.AddAcceptEncodingGzipOptions{}) } -// ResponseError provides the HTTP centric error type wrapping the underlying error -// with the HTTP response value and the deserialized RequestID. +// ResponseError provides the HTTP centric error type wrapping the underlying +// error with the HTTP response value and the deserialized RequestID. type ResponseError interface { error @@ -603,8 +689,8 @@ type ResponseError interface { var _ ResponseError = (*s3shared.ResponseError)(nil) -// GetHostIDMetadata retrieves the host id from middleware metadata returns host id -// as string along with a boolean indicating presence of hostId on middleware +// GetHostIDMetadata retrieves the host id from middleware metadata returns host +// id as string along with a boolean indicating presence of hostId on middleware // metadata. func GetHostIDMetadata(metadata middleware.Metadata) (string, bool) { return s3shared.GetHostIDMetadata(metadata) @@ -770,3 +856,32 @@ func addRequestResponseLogging(stack *middleware.Stack, o Options) error { LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), }, middleware.After) } + +type endpointDisableHTTPSMiddleware struct { + EndpointDisableHTTPS bool +} + +func (*endpointDisableHTTPSMiddleware) ID() string { + return "endpointDisableHTTPSMiddleware" +} + +func (m *endpointDisableHTTPSMiddleware) 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) + } + + if m.EndpointDisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) { + req.URL.Scheme = "http" + } + + return next.HandleSerialize(ctx, in) + +} +func addendpointDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { + return stack.Serialize.Insert(&endpointDisableHTTPSMiddleware{ + EndpointDisableHTTPS: o.EndpointOptions.DisableHTTPS, + }, "OperationSerializer", middleware.Before) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_AbortMultipartUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_AbortMultipartUpload.go index 042e848a3..5932f1f2e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_AbortMultipartUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_AbortMultipartUpload.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -19,32 +25,16 @@ import ( // result, it might be necessary to abort a given multipart upload multiple times // in order to completely free all storage consumed by all parts. To verify that // all parts have been removed, so you don't get charged for the part storage, you -// should call the ListParts -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) action and -// ensure that the parts list is empty. For information about permissions required -// to use the multipart upload, see Multipart Upload and Permissions -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html). The -// following operations are related to AbortMultipartUpload: -// -// * -// CreateMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) -// -// * -// UploadPart -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) -// -// * -// CompleteMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) -// -// * -// ListParts -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) -// -// * -// ListMultipartUploads -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) +// should call the ListParts (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) +// action and ensure that the parts list is empty. For information about +// permissions required to use the multipart upload, see Multipart Upload and +// Permissions (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html) +// . The following operations are related to AbortMultipartUpload : +// - CreateMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) +// - UploadPart (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) +// - CompleteMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) +// - ListParts (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) +// - ListMultipartUploads (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) func (c *Client) AbortMultipartUpload(ctx context.Context, params *AbortMultipartUploadInput, optFns ...func(*Options)) (*AbortMultipartUploadOutput, error) { if params == nil { params = &AbortMultipartUploadInput{} @@ -68,17 +58,15 @@ type AbortMultipartUploadInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -99,10 +87,11 @@ type AbortMultipartUploadInput struct { ExpectedBucketOwner *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -130,6 +119,9 @@ func (c *Client) addOperationAbortMultipartUploadMiddlewares(stack *middleware.S if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -157,7 +149,7 @@ func (c *Client) addOperationAbortMultipartUploadMiddlewares(stack *middleware.S if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -169,6 +161,9 @@ func (c *Client) addOperationAbortMultipartUploadMiddlewares(stack *middleware.S if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addAbortMultipartUploadResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpAbortMultipartUploadValidationMiddleware(stack); err != nil { return err } @@ -178,6 +173,9 @@ func (c *Client) addOperationAbortMultipartUploadMiddlewares(stack *middleware.S if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addAbortMultipartUploadUpdateEndpoint(stack, options); err != nil { return err } @@ -193,9 +191,22 @@ func (c *Client) addOperationAbortMultipartUploadMiddlewares(stack *middleware.S if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *AbortMultipartUploadInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opAbortMultipartUpload(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -230,3 +241,139 @@ func addAbortMultipartUploadUpdateEndpoint(stack *middleware.Stack, options Opti DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opAbortMultipartUploadResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opAbortMultipartUploadResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opAbortMultipartUploadResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*AbortMultipartUploadInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addAbortMultipartUploadResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opAbortMultipartUploadResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CompleteMultipartUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CompleteMultipartUpload.go index 95ff64968..babfebcc6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CompleteMultipartUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CompleteMultipartUpload.go @@ -4,19 +4,24 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Completes a multipart upload by assembling previously uploaded parts. You first -// initiate the multipart upload and then upload all parts using the UploadPart -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) operation. -// After successfully uploading all relevant parts of an upload, you call this -// action to complete the upload. Upon receiving this request, Amazon S3 +// initiate the multipart upload and then upload all parts using the UploadPart (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) +// operation. After successfully uploading all relevant parts of an upload, you +// call this action to complete the upload. Upon receiving this request, Amazon S3 // concatenates all the parts in ascending order by part number to create a new // object. In the Complete Multipart Upload request, you must provide the parts // list. You must ensure that the parts list is complete. This action concatenates @@ -26,78 +31,48 @@ import ( // minutes to complete. After Amazon S3 begins processing the request, it sends an // HTTP response header that specifies a 200 OK response. While processing is in // progress, Amazon S3 periodically sends white space characters to keep the -// connection from timing out. Because a request could fail after the initial 200 -// OK response has been sent, it is important that you check the response body to -// determine whether the request succeeded. Note that if CompleteMultipartUpload -// fails, applications should be prepared to retry the failed requests. For more -// information, see Amazon S3 Error Best Practices -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/ErrorBestPractices.html). You -// cannot use Content-Type: application/x-www-form-urlencoded with Complete +// connection from timing out. A request could fail after the initial 200 OK +// response has been sent. This means that a 200 OK response can contain either a +// success or an error. If you call the S3 API directly, make sure to design your +// application to parse the contents of the response and handle it appropriately. +// If you use Amazon Web Services SDKs, SDKs handle this condition. The SDKs detect +// the embedded error and apply error handling per your configuration settings +// (including automatically retrying the request as appropriate). If the condition +// persists, the SDKs throws an exception (or, for the SDKs that don't use +// exceptions, they return the error). Note that if CompleteMultipartUpload fails, +// applications should be prepared to retry the failed requests. For more +// information, see Amazon S3 Error Best Practices (https://docs.aws.amazon.com/AmazonS3/latest/dev/ErrorBestPractices.html) +// . You cannot use Content-Type: application/x-www-form-urlencoded with Complete // Multipart Upload requests. Also, if you do not provide a Content-Type header, // CompleteMultipartUpload returns a 200 OK response. For more information about -// multipart uploads, see Uploading Objects Using Multipart Upload -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html). For -// information about permissions required to use the multipart upload API, see -// Multipart Upload and Permissions -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html). -// CompleteMultipartUpload has the following special errors: +// multipart uploads, see Uploading Objects Using Multipart Upload (https://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html) +// . For information about permissions required to use the multipart upload API, +// see Multipart Upload and Permissions (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html) +// . CompleteMultipartUpload has the following special errors: +// - Error code: EntityTooSmall +// - Description: Your proposed upload is smaller than the minimum allowed +// object size. Each part must be at least 5 MB in size, except the last part. +// - 400 Bad Request +// - Error code: InvalidPart +// - Description: One or more of the specified parts could not be found. The +// part might not have been uploaded, or the specified entity tag might not have +// matched the part's entity tag. +// - 400 Bad Request +// - Error code: InvalidPartOrder +// - Description: The list of parts was not in ascending order. The parts list +// must be specified in order by part number. +// - 400 Bad Request +// - Error code: NoSuchUpload +// - Description: The specified multipart upload does not exist. The upload ID +// might be invalid, or the multipart upload might have been aborted or completed. +// - 404 Not Found // -// * Error code: -// EntityTooSmall -// -// * Description: Your proposed upload is smaller than the minimum -// allowed object size. Each part must be at least 5 MB in size, except the last -// part. -// -// * 400 Bad Request -// -// * Error code: InvalidPart -// -// * Description: One or more -// of the specified parts could not be found. The part might not have been -// uploaded, or the specified entity tag might not have matched the part's entity -// tag. -// -// * 400 Bad Request -// -// * Error code: InvalidPartOrder -// -// * Description: The list -// of parts was not in ascending order. The parts list must be specified in order -// by part number. -// -// * 400 Bad Request -// -// * Error code: NoSuchUpload -// -// * Description: -// The specified multipart upload does not exist. The upload ID might be invalid, -// or the multipart upload might have been aborted or completed. -// -// * 404 Not -// Found -// -// The following operations are related to CompleteMultipartUpload: -// -// * -// CreateMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) -// -// * -// UploadPart -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) -// -// * -// AbortMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) -// -// * -// ListParts -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) -// -// * -// ListMultipartUploads -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) +// The following operations are related to CompleteMultipartUpload : +// - CreateMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) +// - UploadPart (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) +// - AbortMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) +// - ListParts (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) +// - ListMultipartUploads (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) func (c *Client) CompleteMultipartUpload(ctx context.Context, params *CompleteMultipartUploadInput, optFns ...func(*Options)) (*CompleteMultipartUploadOutput, error) { if params == nil { params = &CompleteMultipartUploadInput{} @@ -121,17 +96,15 @@ type CompleteMultipartUploadInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -149,32 +122,28 @@ type CompleteMultipartUploadInput struct { // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 32-bit CRC32 checksum of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumCRC32 *string // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 32-bit CRC32C checksum of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumCRC32C *string // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 160-bit SHA-1 digest of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumSHA1 *string // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 256-bit SHA-256 digest of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumSHA256 *string @@ -187,31 +156,29 @@ type CompleteMultipartUploadInput struct { MultipartUpload *types.CompletedMultipartUpload // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer // The server-side encryption (SSE) algorithm used to encrypt the object. This // parameter is needed only when the object was created using a checksum algorithm. - // For more information, see Protecting data using SSE-C keys - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) + // For more information, see Protecting data using SSE-C keys (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) // in the Amazon S3 User Guide. SSECustomerAlgorithm *string // The server-side encryption (SSE) customer managed key. This parameter is needed // only when the object was created using a checksum algorithm. For more - // information, see Protecting data using SSE-C keys - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) + // information, see Protecting data using SSE-C keys (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) // in the Amazon S3 User Guide. SSECustomerKey *string // The MD5 server-side encryption (SSE) customer managed key. This parameter is // needed only when the object was created using a checksum algorithm. For more - // information, see Protecting data using SSE-C keys - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) + // information, see Protecting data using SSE-C keys (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) // in the Amazon S3 User Guide. SSECustomerKeyMD5 *string @@ -227,52 +194,46 @@ type CompleteMultipartUploadOutput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. Bucket *string // Indicates whether the multipart upload uses an S3 Bucket Key for server-side - // encryption with Amazon Web Services KMS (SSE-KMS). + // encryption with Key Management Service (KMS) keys (SSE-KMS). BucketKeyEnabled bool // The base64-encoded, 32-bit CRC32 checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32 *string // The base64-encoded, 32-bit CRC32C checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32C *string // The base64-encoded, 160-bit SHA-1 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA1 *string // The base64-encoded, 256-bit SHA-256 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA256 *string @@ -282,13 +243,12 @@ type CompleteMultipartUploadOutput struct { // data. If the entity tag is not an MD5 digest of the object data, it will contain // one or more nonhexadecimal characters and/or will consist of less than 32 or // more than 32 hexadecimal digits. For more information about how the entity tag - // is calculated, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // is calculated, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ETag *string - // If the object expiration is configured, this will contain the expiration date - // (expiry-date) and rule ID (rule-id). The value of rule-id is URL-encoded. + // If the object expiration is configured, this will contain the expiration date ( + // expiry-date ) and rule ID ( rule-id ). The value of rule-id is URL-encoded. Expiration *string // The object key of the newly created object. @@ -301,19 +261,16 @@ type CompleteMultipartUploadOutput struct { // request. RequestCharged types.RequestCharged - // If present, specifies the ID of the Amazon Web Services Key Management Service - // (Amazon Web Services KMS) symmetric customer managed key that was used for the - // object. + // If present, specifies the ID of the Key Management Service (KMS) symmetric + // encryption customer managed key that was used for the object. SSEKMSKeyId *string - // If you specified server-side encryption either with an Amazon S3-managed - // encryption key or an Amazon Web Services KMS key in your initiate multipart - // upload request, the response includes this header. It confirms the encryption - // algorithm that Amazon S3 used to encrypt the object. + // The server-side encryption algorithm used when storing this object in Amazon S3 + // (for example, AES256 , aws:kms ). ServerSideEncryption types.ServerSideEncryption - // Version ID of the newly created object, in case the bucket has versioning turned - // on. + // Version ID of the newly created object, in case the bucket has versioning + // turned on. VersionId *string // Metadata pertaining to the operation's result. @@ -331,6 +288,9 @@ func (c *Client) addOperationCompleteMultipartUploadMiddlewares(stack *middlewar if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -358,7 +318,7 @@ func (c *Client) addOperationCompleteMultipartUploadMiddlewares(stack *middlewar if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -370,6 +330,9 @@ func (c *Client) addOperationCompleteMultipartUploadMiddlewares(stack *middlewar if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addCompleteMultipartUploadResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpCompleteMultipartUploadValidationMiddleware(stack); err != nil { return err } @@ -379,6 +342,9 @@ func (c *Client) addOperationCompleteMultipartUploadMiddlewares(stack *middlewar if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addCompleteMultipartUploadUpdateEndpoint(stack, options); err != nil { return err } @@ -397,9 +363,22 @@ func (c *Client) addOperationCompleteMultipartUploadMiddlewares(stack *middlewar if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *CompleteMultipartUploadInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opCompleteMultipartUpload(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -434,3 +413,139 @@ func addCompleteMultipartUploadUpdateEndpoint(stack *middleware.Stack, options O DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opCompleteMultipartUploadResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opCompleteMultipartUploadResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opCompleteMultipartUploadResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*CompleteMultipartUploadInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addCompleteMultipartUploadResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opCompleteMultipartUploadResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CopyObject.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CopyObject.go index 477900778..97516a258 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CopyObject.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CopyObject.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "time" @@ -18,146 +24,138 @@ import ( // up to 5 GB in size in a single atomic action using this API. However, to copy an // object greater than 5 GB, you must use the multipart upload Upload Part - Copy // (UploadPartCopy) API. For more information, see Copy Object Using the REST -// Multipart Upload API -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/CopyingObjctsUsingRESTMPUapi.html). -// All copy requests must be authenticated. Additionally, you must have read access -// to the source object and write access to the destination bucket. For more -// information, see REST Authentication -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html). Both -// the Region that you want to copy the object from and the Region that you want to -// copy the object to must be enabled for your account. A copy request might return -// an error when Amazon S3 receives the copy request or while Amazon S3 is copying -// the files. If the error occurs before the copy action starts, you receive a -// standard Amazon S3 error. If the error occurs during the copy operation, the -// error response is embedded in the 200 OK response. This means that a 200 OK -// response can contain either a success or an error. Design your application to -// parse the contents of the response and handle it appropriately. If the copy is -// successful, you receive a response with information about the copied object. If -// the request is an HTTP 1.1 request, the response is chunk encoded. If it were -// not, it would not contain the content-length, and you would need to read the -// entire body. The copy request charge is based on the storage class and Region -// that you specify for the destination object. For pricing information, see Amazon -// S3 pricing (http://aws.amazon.com/s3/pricing/). Amazon S3 transfer acceleration -// does not support cross-Region copies. If you request a cross-Region copy using a -// transfer acceleration endpoint, you get a 400 Bad Request error. For more -// information, see Transfer Acceleration -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html). -// Metadata When copying an object, you can preserve all metadata (default) or -// specify new metadata. However, the ACL is not preserved and is set to private -// for the user making the request. To override the default ACL setting, specify a -// new ACL when generating a copy request. For more information, see Using ACLs -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/S3_ACLs_UsingACLs.html). To -// specify whether you want the object metadata copied from the source object or -// replaced with metadata provided in the request, you can optionally add the +// Multipart Upload API (https://docs.aws.amazon.com/AmazonS3/latest/dev/CopyingObjctsUsingRESTMPUapi.html) +// . All copy requests must be authenticated. Additionally, you must have read +// access to the source object and write access to the destination bucket. For more +// information, see REST Authentication (https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html) +// . Both the Region that you want to copy the object from and the Region that you +// want to copy the object to must be enabled for your account. A copy request +// might return an error when Amazon S3 receives the copy request or while Amazon +// S3 is copying the files. If the error occurs before the copy action starts, you +// receive a standard Amazon S3 error. If the error occurs during the copy +// operation, the error response is embedded in the 200 OK response. This means +// that a 200 OK response can contain either a success or an error. If you call +// the S3 API directly, make sure to design your application to parse the contents +// of the response and handle it appropriately. If you use Amazon Web Services +// SDKs, SDKs handle this condition. The SDKs detect the embedded error and apply +// error handling per your configuration settings (including automatically retrying +// the request as appropriate). If the condition persists, the SDKs throws an +// exception (or, for the SDKs that don't use exceptions, they return the error). +// If the copy is successful, you receive a response with information about the +// copied object. If the request is an HTTP 1.1 request, the response is chunk +// encoded. If it were not, it would not contain the content-length, and you would +// need to read the entire body. The copy request charge is based on the storage +// class and Region that you specify for the destination object. The request can +// also result in a data retrieval charge for the source if the source storage +// class bills for data retrieval. For pricing information, see Amazon S3 pricing (http://aws.amazon.com/s3/pricing/) +// . Amazon S3 transfer acceleration does not support cross-Region copies. If you +// request a cross-Region copy using a transfer acceleration endpoint, you get a +// 400 Bad Request error. For more information, see Transfer Acceleration (https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html) +// . Metadata When copying an object, you can preserve all metadata (the default) +// or specify new metadata. However, the access control list (ACL) is not preserved +// and is set to private for the user making the request. To override the default +// ACL setting, specify a new ACL when generating a copy request. For more +// information, see Using ACLs (https://docs.aws.amazon.com/AmazonS3/latest/dev/S3_ACLs_UsingACLs.html) +// . To specify whether you want the object metadata copied from the source object +// or replaced with metadata provided in the request, you can optionally add the // x-amz-metadata-directive header. When you grant permissions, you can use the // s3:x-amz-metadata-directive condition key to enforce certain metadata behavior // when objects are uploaded. For more information, see Specifying Conditions in a -// Policy -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/amazon-s3-policy-keys.html) in -// the Amazon S3 User Guide. For a complete list of Amazon S3-specific condition -// keys, see Actions, Resources, and Condition Keys for Amazon S3 -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/list_amazons3.html). -// x-amz-copy-source-if Headers To only copy an object under certain conditions, -// such as whether the Etag matches or whether the object was modified before or -// after a specified date, use the following request parameters: +// Policy (https://docs.aws.amazon.com/AmazonS3/latest/dev/amazon-s3-policy-keys.html) +// in the Amazon S3 User Guide. For a complete list of Amazon S3-specific condition +// keys, see Actions, Resources, and Condition Keys for Amazon S3 (https://docs.aws.amazon.com/AmazonS3/latest/dev/list_amazons3.html) +// . x-amz-website-redirect-location is unique to each object and must be +// specified in the request headers to copy the value. x-amz-copy-source-if Headers +// To only copy an object under certain conditions, such as whether the Etag +// matches or whether the object was modified before or after a specified date, use +// the following request parameters: +// - x-amz-copy-source-if-match +// - x-amz-copy-source-if-none-match +// - x-amz-copy-source-if-unmodified-since +// - x-amz-copy-source-if-modified-since // -// * -// x-amz-copy-source-if-match -// -// * x-amz-copy-source-if-none-match -// -// * -// x-amz-copy-source-if-unmodified-since -// -// * x-amz-copy-source-if-modified-since -// -// If -// both the x-amz-copy-source-if-match and x-amz-copy-source-if-unmodified-since +// If both the x-amz-copy-source-if-match and x-amz-copy-source-if-unmodified-since // headers are present in the request and evaluate as follows, Amazon S3 returns // 200 OK and copies the data: +// - x-amz-copy-source-if-match condition evaluates to true +// - x-amz-copy-source-if-unmodified-since condition evaluates to false // -// * x-amz-copy-source-if-match condition evaluates to -// true -// -// * x-amz-copy-source-if-unmodified-since condition evaluates to false -// -// If -// both the x-amz-copy-source-if-none-match and x-amz-copy-source-if-modified-since -// headers are present in the request and evaluate as follows, Amazon S3 returns -// the 412 Precondition Failed response code: -// -// * x-amz-copy-source-if-none-match -// condition evaluates to false +// If both the x-amz-copy-source-if-none-match and +// x-amz-copy-source-if-modified-since headers are present in the request and +// evaluate as follows, Amazon S3 returns the 412 Precondition Failed response +// code: +// - x-amz-copy-source-if-none-match condition evaluates to false +// - x-amz-copy-source-if-modified-since condition evaluates to true // -// * x-amz-copy-source-if-modified-since condition -// evaluates to true -// -// All headers with the x-amz- prefix, including -// x-amz-copy-source, must be signed. Server-side encryption When you perform a -// CopyObject operation, you can optionally use the appropriate encryption-related -// headers to encrypt the object using server-side encryption with Amazon Web -// Services managed encryption keys (SSE-S3 or SSE-KMS) or a customer-provided -// encryption key. With server-side encryption, Amazon S3 encrypts your data as it -// writes it to disks in its data centers and decrypts the data when you access it. -// For more information about server-side encryption, see Using Server-Side -// Encryption -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html). If -// a target object uses SSE-KMS, you can enable an S3 Bucket Key for the object. -// For more information, see Amazon S3 Bucket Keys -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html) in the Amazon -// S3 User Guide. Access Control List (ACL)-Specific Request Headers When copying -// an object, you can optionally use headers to grant ACL-based permissions. By -// default, all objects are private. Only the owner has full access control. When -// adding a new object, you can grant permissions to individual Amazon Web Services -// accounts or to predefined groups defined by Amazon S3. These permissions are -// then added to the ACL on the object. For more information, see Access Control -// List (ACL) Overview -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html) and Managing -// ACLs Using the REST API -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-using-rest-api.html). If -// the bucket that you're copying objects to uses the bucket owner enforced setting -// for S3 Object Ownership, ACLs are disabled and no longer affect permissions. -// Buckets that use this setting only accept PUT requests that don't specify an ACL -// or PUT requests that specify bucket owner full control ACLs, such as the -// bucket-owner-full-control canned ACL or an equivalent form of this ACL expressed -// in the XML format. For more information, see Controlling ownership of objects -// and disabling ACLs -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) +// All headers with the x-amz- prefix, including x-amz-copy-source , must be +// signed. Server-side encryption Amazon S3 automatically encrypts all new objects +// that are copied to an S3 bucket. When copying an object, if you don't specify +// encryption information in your copy request, the encryption setting of the +// target object is set to the default encryption configuration of the destination +// bucket. By default, all buckets have a base level of encryption configuration +// that uses server-side encryption with Amazon S3 managed keys (SSE-S3). If the +// destination bucket has a default encryption configuration that uses server-side +// encryption with Key Management Service (KMS) keys (SSE-KMS), dual-layer +// server-side encryption with Amazon Web Services KMS keys (DSSE-KMS), or +// server-side encryption with customer-provided encryption keys (SSE-C), Amazon S3 +// uses the corresponding KMS key, or a customer-provided key to encrypt the target +// object copy. When you perform a CopyObject operation, if you want to use a +// different type of encryption setting for the target object, you can use other +// appropriate encryption-related headers to encrypt the target object with a KMS +// key, an Amazon S3 managed key, or a customer-provided key. With server-side +// encryption, Amazon S3 encrypts your data as it writes your data to disks in its +// data centers and decrypts the data when you access it. If the encryption setting +// in your request is different from the default encryption configuration of the +// destination bucket, the encryption setting in your request takes precedence. If +// the source object for the copy is stored in Amazon S3 using SSE-C, you must +// provide the necessary encryption information in your request so that Amazon S3 +// can decrypt the object for copying. For more information about server-side +// encryption, see Using Server-Side Encryption (https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html) +// . If a target object uses SSE-KMS, you can enable an S3 Bucket Key for the +// object. For more information, see Amazon S3 Bucket Keys (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html) +// in the Amazon S3 User Guide. Access Control List (ACL)-Specific Request Headers +// When copying an object, you can optionally use headers to grant ACL-based +// permissions. By default, all objects are private. Only the owner has full access +// control. When adding a new object, you can grant permissions to individual +// Amazon Web Services accounts or to predefined groups that are defined by Amazon +// S3. These permissions are then added to the ACL on the object. For more +// information, see Access Control List (ACL) Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html) +// and Managing ACLs Using the REST API (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-using-rest-api.html) +// . If the bucket that you're copying objects to uses the bucket owner enforced +// setting for S3 Object Ownership, ACLs are disabled and no longer affect +// permissions. Buckets that use this setting only accept PUT requests that don't +// specify an ACL or PUT requests that specify bucket owner full control ACLs, +// such as the bucket-owner-full-control canned ACL or an equivalent form of this +// ACL expressed in the XML format. For more information, see Controlling +// ownership of objects and disabling ACLs (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) // in the Amazon S3 User Guide. If your bucket uses the bucket owner enforced // setting for Object Ownership, all objects written to the bucket by any account // will be owned by the bucket owner. Checksums When copying an object, if it has a // checksum, that checksum will be copied to the new object by default. When you -// copy the object over, you may optionally specify a different checksum algorithm +// copy the object over, you can optionally specify a different checksum algorithm // to use with the x-amz-checksum-algorithm header. Storage Class Options You can // use the CopyObject action to change the storage class of an object that is -// already stored in Amazon S3 using the StorageClass parameter. For more -// information, see Storage Classes -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html) in -// the Amazon S3 User Guide. Versioning By default, x-amz-copy-source identifies -// the current version of an object to copy. If the current version is a delete -// marker, Amazon S3 behaves as if the object was deleted. To copy a different -// version, use the versionId subresource. If you enable versioning on the target -// bucket, Amazon S3 generates a unique version ID for the object being copied. -// This version ID is different from the version ID of the source object. Amazon S3 -// returns the version ID of the copied object in the x-amz-version-id response -// header in the response. If you do not enable versioning or suspend it on the -// target bucket, the version ID that Amazon S3 generates is always null. If the -// source object's storage class is GLACIER, you must restore a copy of this object +// already stored in Amazon S3 by using the StorageClass parameter. For more +// information, see Storage Classes (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html) +// in the Amazon S3 User Guide. If the source object's storage class is GLACIER or +// DEEP_ARCHIVE, or the object's storage class is INTELLIGENT_TIERING and it's S3 +// Intelligent-Tiering access tier (https://docs.aws.amazon.com/AmazonS3/latest/userguide/intelligent-tiering-overview.html#intel-tiering-tier-definition) +// is Archive Access or Deep Archive Access, you must restore a copy of this object // before you can use it as a source object for the copy operation. For more -// information, see RestoreObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_RestoreObject.html). The -// following operations are related to CopyObject: -// -// * PutObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) -// -// * -// GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) -// -// For more -// information, see Copying Objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/CopyingObjectsExamples.html). +// information, see RestoreObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_RestoreObject.html) +// . For more information, see Copying Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/CopyingObjectsExamples.html) +// . Versioning By default, x-amz-copy-source header identifies the current +// version of an object to copy. If the current version is a delete marker, Amazon +// S3 behaves as if the object was deleted. To copy a different version, use the +// versionId subresource. If you enable versioning on the target bucket, Amazon S3 +// generates a unique version ID for the object being copied. This version ID is +// different from the version ID of the source object. Amazon S3 returns the +// version ID of the copied object in the x-amz-version-id response header in the +// response. If you do not enable versioning or suspend it on the target bucket, +// the version ID that Amazon S3 generates is always null. The following operations +// are related to CopyObject : +// - PutObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) +// - GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) func (c *Client) CopyObject(ctx context.Context, params *CopyObjectInput, optFns ...func(*Options)) (*CopyObjectOutput, error) { if params == nil { params = &CopyObjectInput{} @@ -175,58 +173,53 @@ func (c *Client) CopyObject(ctx context.Context, params *CopyObjectInput, optFns type CopyObjectInput struct { - // The name of the destination bucket. When using this action with an access point, - // you must direct requests to the access point hostname. The access point hostname - // takes the form AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. - // When using this action with an access point through the Amazon Web Services - // SDKs, you provide the access point ARN in place of the bucket name. For more - // information about access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts + // The name of the destination bucket. When using this action with an access + // point, you must direct requests to the access point hostname. The access point // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this + // action with an access point through the Amazon Web Services SDKs, you provide + // the access point ARN in place of the bucket name. For more information about + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string - // Specifies the source object for the copy operation. You specify the value in one - // of two formats, depending on whether you want to access the source object - // through an access point - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-points.html): - // - // * - // For objects not accessed through an access point, specify the name of the source - // bucket and the key of the source object, separated by a slash (/). For example, - // to copy the object reports/january.pdf from the bucket awsexamplebucket, use - // awsexamplebucket/reports/january.pdf. The value must be URL-encoded. - // - // * For - // objects accessed through access points, specify the Amazon Resource Name (ARN) - // of the object as accessed through the access point, in the format - // arn:aws:s3:::accesspoint//object/. For example, to copy the object - // reports/january.pdf through access point my-access-point owned by account - // 123456789012 in Region us-west-2, use the URL encoding of - // arn:aws:s3:us-west-2:123456789012:accesspoint/my-access-point/object/reports/january.pdf. - // The value must be URL encoded. Amazon S3 supports copy operations using access - // points only when the source and destination buckets are in the same Amazon Web - // Services Region. Alternatively, for objects accessed through Amazon S3 on - // Outposts, specify the ARN of the object as accessed in the format - // arn:aws:s3-outposts:::outpost//object/. For example, to copy the object - // reports/january.pdf through outpost my-outpost owned by account 123456789012 in - // Region us-west-2, use the URL encoding of - // arn:aws:s3-outposts:us-west-2:123456789012:outpost/my-outpost/object/reports/january.pdf. - // The value must be URL-encoded. - // - // To copy a specific version of an object, append - // ?versionId= to the value (for example, - // awsexamplebucket/reports/january.pdf?versionId=QUpfdndhfd8438MNFDN93jdnJFkdmqnh893). - // If you don't specify a version ID, Amazon S3 copies the latest version of the + // Specifies the source object for the copy operation. You specify the value in + // one of two formats, depending on whether you want to access the source object + // through an access point (https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-points.html) + // : + // - For objects not accessed through an access point, specify the name of the + // source bucket and the key of the source object, separated by a slash (/). For + // example, to copy the object reports/january.pdf from the bucket + // awsexamplebucket , use awsexamplebucket/reports/january.pdf . The value must + // be URL-encoded. + // - For objects accessed through access points, specify the Amazon Resource + // Name (ARN) of the object as accessed through the access point, in the format + // arn:aws:s3:::accesspoint//object/ . For example, to copy the object + // reports/january.pdf through access point my-access-point owned by account + // 123456789012 in Region us-west-2 , use the URL encoding of + // arn:aws:s3:us-west-2:123456789012:accesspoint/my-access-point/object/reports/january.pdf + // . The value must be URL encoded. Amazon S3 supports copy operations using access + // points only when the source and destination buckets are in the same Amazon Web + // Services Region. Alternatively, for objects accessed through Amazon S3 on + // Outposts, specify the ARN of the object as accessed in the format + // arn:aws:s3-outposts:::outpost//object/ . For example, to copy the object + // reports/january.pdf through outpost my-outpost owned by account 123456789012 + // in Region us-west-2 , use the URL encoding of + // arn:aws:s3-outposts:us-west-2:123456789012:outpost/my-outpost/object/reports/january.pdf + // . The value must be URL-encoded. + // To copy a specific version of an object, append ?versionId= to the value (for + // example, + // awsexamplebucket/reports/january.pdf?versionId=QUpfdndhfd8438MNFDN93jdnJFkdmqnh893 + // ). If you don't specify a version ID, Amazon S3 copies the latest version of the // source object. // // This member is required. @@ -237,23 +230,22 @@ type CopyObjectInput struct { // This member is required. Key *string - // The canned ACL to apply to the object. This action is not supported by Amazon S3 - // on Outposts. + // The canned ACL to apply to the object. This action is not supported by Amazon + // S3 on Outposts. ACL types.ObjectCannedACL // Specifies whether Amazon S3 should use an S3 Bucket Key for object encryption - // with server-side encryption using AWS KMS (SSE-KMS). Setting this header to true - // causes Amazon S3 to use an S3 Bucket Key for object encryption with SSE-KMS. - // Specifying this header with a COPY action doesn’t affect bucket-level settings - // for S3 Bucket Key. + // with server-side encryption using Key Management Service (KMS) keys (SSE-KMS). + // Setting this header to true causes Amazon S3 to use an S3 Bucket Key for object + // encryption with SSE-KMS. Specifying this header with a COPY action doesn’t + // affect bucket-level settings for S3 Bucket Key. BucketKeyEnabled bool // Specifies caching behavior along the request/reply chain. CacheControl *string - // Indicates the algorithm you want Amazon S3 to use to create the checksum for the - // object. For more information, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Indicates the algorithm you want Amazon S3 to use to create the checksum for + // the object. For more information, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumAlgorithm types.ChecksumAlgorithm @@ -318,8 +310,8 @@ type CopyObjectInput struct { // supported by Amazon S3 on Outposts. GrantRead *string - // Allows grantee to read the object ACL. This action is not supported by Amazon S3 - // on Outposts. + // Allows grantee to read the object ACL. This action is not supported by Amazon + // S3 on Outposts. GrantReadACP *string // Allows grantee to write the ACL for the applicable object. This action is not @@ -329,8 +321,8 @@ type CopyObjectInput struct { // A map of metadata to store with the object in S3. Metadata map[string]string - // Specifies whether the metadata is copied from the source object or replaced with - // metadata provided in the request. + // Specifies whether the metadata is copied from the source object or replaced + // with metadata provided in the request. MetadataDirective types.MetadataDirective // Specifies whether you want to apply a legal hold to the copied object. @@ -343,10 +335,11 @@ type CopyObjectInput struct { ObjectLockRetainUntilDate *time.Time // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -371,30 +364,28 @@ type CopyObjectInput struct { // JSON with the encryption context key-value pairs. SSEKMSEncryptionContext *string - // Specifies the Amazon Web Services KMS key ID to use for object encryption. All - // GET and PUT requests for an object protected by Amazon Web Services KMS will - // fail if not made via SSL or using SigV4. For information about configuring using - // any of the officially supported Amazon Web Services SDKs and Amazon Web Services - // CLI, see Specifying the Signature Version in Request Authentication - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAWSSDK.html#specify-signature-version) + // Specifies the KMS ID (Key ID, Key ARN, or Key Alias) to use for object + // encryption. All GET and PUT requests for an object protected by KMS will fail if + // they're not made via SSL or using SigV4. For information about configuring any + // of the officially supported Amazon Web Services SDKs and Amazon Web Services + // CLI, see Specifying the Signature Version in Request Authentication (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAWSSDK.html#specify-signature-version) // in the Amazon S3 User Guide. SSEKMSKeyId *string // The server-side encryption algorithm used when storing this object in Amazon S3 - // (for example, AES256, aws:kms). + // (for example, AES256 , aws:kms , aws:kms:dsse ). ServerSideEncryption types.ServerSideEncryption - // By default, Amazon S3 uses the STANDARD Storage Class to store newly created - // objects. The STANDARD storage class provides high durability and high - // availability. Depending on performance needs, you can specify a different - // Storage Class. Amazon S3 on Outposts only uses the OUTPOSTS Storage Class. For - // more information, see Storage Classes - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html) in - // the Amazon S3 User Guide. + // If the x-amz-storage-class header is not used, the copied object will be stored + // in the STANDARD Storage Class by default. The STANDARD storage class provides + // high durability and high availability. Depending on performance needs, you can + // specify a different Storage Class. Amazon S3 on Outposts only uses the OUTPOSTS + // Storage Class. For more information, see Storage Classes (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html) + // in the Amazon S3 User Guide. StorageClass types.StorageClass // The tag-set for the object destination object this value must be used in - // conjunction with the TaggingDirective. The tag-set must be encoded as URL Query + // conjunction with the TaggingDirective . The tag-set must be encoded as URL Query // parameters. Tagging *string @@ -404,7 +395,9 @@ type CopyObjectInput struct { // If the bucket is configured as a website, redirects requests for this object to // another object in the same bucket or to an external URL. Amazon S3 stores the - // value of this header in the object metadata. + // value of this header in the object metadata. This value is unique to each object + // and is not copied when using the x-amz-metadata-directive header. Instead, you + // may opt to provide this header in combination with the directive. WebsiteRedirectLocation *string noSmithyDocumentSerde @@ -413,7 +406,7 @@ type CopyObjectInput struct { type CopyObjectOutput struct { // Indicates whether the copied object uses an S3 Bucket Key for server-side - // encryption with Amazon Web Services KMS (SSE-KMS). + // encryption with Key Management Service (KMS) keys (SSE-KMS). BucketKeyEnabled bool // Container for all response elements. @@ -429,13 +422,14 @@ type CopyObjectOutput struct { // request. RequestCharged types.RequestCharged - // If server-side encryption with a customer-provided encryption key was requested, - // the response will include this header confirming the encryption algorithm used. + // If server-side encryption with a customer-provided encryption key was + // requested, the response will include this header confirming the encryption + // algorithm used. SSECustomerAlgorithm *string - // If server-side encryption with a customer-provided encryption key was requested, - // the response will include this header to provide round-trip message integrity - // verification of the customer-provided encryption key. + // If server-side encryption with a customer-provided encryption key was + // requested, the response will include this header to provide round-trip message + // integrity verification of the customer-provided encryption key. SSECustomerKeyMD5 *string // If present, specifies the Amazon Web Services KMS Encryption Context to use for @@ -443,13 +437,12 @@ type CopyObjectOutput struct { // holding JSON with the encryption context key-value pairs. SSEKMSEncryptionContext *string - // If present, specifies the ID of the Amazon Web Services Key Management Service - // (Amazon Web Services KMS) symmetric customer managed key that was used for the - // object. + // If present, specifies the ID of the Key Management Service (KMS) symmetric + // encryption customer managed key that was used for the object. SSEKMSKeyId *string // The server-side encryption algorithm used when storing this object in Amazon S3 - // (for example, AES256, aws:kms). + // (for example, AES256 , aws:kms , aws:kms:dsse ). ServerSideEncryption types.ServerSideEncryption // Version ID of the newly created copy. @@ -470,6 +463,9 @@ func (c *Client) addOperationCopyObjectMiddlewares(stack *middleware.Stack, opti if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -497,7 +493,7 @@ func (c *Client) addOperationCopyObjectMiddlewares(stack *middleware.Stack, opti if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -509,6 +505,9 @@ func (c *Client) addOperationCopyObjectMiddlewares(stack *middleware.Stack, opti if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addCopyObjectResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpCopyObjectValidationMiddleware(stack); err != nil { return err } @@ -518,6 +517,9 @@ func (c *Client) addOperationCopyObjectMiddlewares(stack *middleware.Stack, opti if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addCopyObjectUpdateEndpoint(stack, options); err != nil { return err } @@ -536,9 +538,22 @@ func (c *Client) addOperationCopyObjectMiddlewares(stack *middleware.Stack, opti if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *CopyObjectInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opCopyObject(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -548,8 +563,9 @@ func newServiceMetadataMiddleware_opCopyObject(region string) *awsmiddleware.Reg } } -// getCopyObjectBucketMember returns a pointer to string denoting a provided bucket -// member valueand a boolean indicating if the input has a modeled bucket name, +// getCopyObjectBucketMember returns a pointer to string denoting a provided +// bucket member valueand a boolean indicating if the input has a modeled bucket +// name, func getCopyObjectBucketMember(input interface{}) (*string, bool) { in := input.(*CopyObjectInput) if in.Bucket == nil { @@ -572,3 +588,139 @@ func addCopyObjectUpdateEndpoint(stack *middleware.Stack, options Options) error DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opCopyObjectResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opCopyObjectResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opCopyObjectResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*CopyObjectInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addCopyObjectResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opCopyObjectResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CreateBucket.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CreateBucket.go index 27322a2c6..9da6f8b9c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CreateBucket.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CreateBucket.go @@ -4,11 +4,18 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -16,121 +23,63 @@ import ( // and have a valid Amazon Web Services Access Key ID to authenticate requests. // Anonymous requests are never allowed to create buckets. By creating the bucket, // you become the bucket owner. Not every string is an acceptable bucket name. For -// information about bucket naming restrictions, see Bucket naming rules -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html). -// If you want to create an Amazon S3 on Outposts bucket, see Create Bucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_CreateBucket.html). -// By default, the bucket is created in the US East (N. Virginia) Region. You can -// optionally specify a Region in the request body. You might choose a Region to -// optimize latency, minimize costs, or address regulatory requirements. For -// example, if you reside in Europe, you will probably find it advantageous to -// create buckets in the Europe (Ireland) Region. For more information, see -// Accessing a bucket -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro). -// If you send your create bucket request to the s3.amazonaws.com endpoint, the -// request goes to the us-east-1 Region. Accordingly, the signature calculations in -// Signature Version 4 must use us-east-1 as the Region, even if the location +// information about bucket naming restrictions, see Bucket naming rules (https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html) +// . If you want to create an Amazon S3 on Outposts bucket, see Create Bucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_CreateBucket.html) +// . By default, the bucket is created in the US East (N. Virginia) Region. You can +// optionally specify a Region in the request body. To constrain the bucket +// creation to a specific Region, you can use LocationConstraint (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucketConfiguration.html) +// condition key. You might choose a Region to optimize latency, minimize costs, or +// address regulatory requirements. For example, if you reside in Europe, you will +// probably find it advantageous to create buckets in the Europe (Ireland) Region. +// For more information, see Accessing a bucket (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro) +// . If you send your create bucket request to the s3.amazonaws.com endpoint, the +// request goes to the us-east-1 Region. Accordingly, the signature calculations +// in Signature Version 4 must use us-east-1 as the Region, even if the location // constraint in the request specifies another Region where the bucket is to be // created. If you create a bucket in a Region other than US East (N. Virginia), // your application must be able to handle 307 redirect. For more information, see -// Virtual hosting of buckets -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html). Access -// control lists (ACLs) When creating a bucket using this operation, you can -// optionally configure the bucket ACL to specify the accounts or groups that -// should be granted specific permissions on the bucket. If your CreateBucket -// request sets bucket owner enforced for S3 Object Ownership and specifies a -// bucket ACL that provides access to an external Amazon Web Services account, your -// request fails with a 400 error and returns the -// InvalidBucketAclWithObjectOwnership error code. For more information, see -// Controlling object ownership -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) -// in the Amazon S3 User Guide. There are two ways to grant the appropriate -// permissions using the request headers. +// Virtual hosting of buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html) +// . Permissions In addition to s3:CreateBucket , the following permissions are +// required when your CreateBucket request includes specific headers: +// - Access control lists (ACLs) - If your CreateBucket request specifies access +// control list (ACL) permissions and the ACL is public-read, public-read-write, +// authenticated-read, or if you specify access permissions explicitly through any +// other ACL, both s3:CreateBucket and s3:PutBucketAcl permissions are needed. If +// the ACL for the CreateBucket request is private or if the request doesn't +// specify any ACLs, only s3:CreateBucket permission is needed. +// - Object Lock - If ObjectLockEnabledForBucket is set to true in your +// CreateBucket request, s3:PutBucketObjectLockConfiguration and +// s3:PutBucketVersioning permissions are required. +// - S3 Object Ownership - If your CreateBucket request includes the +// x-amz-object-ownership header, then the s3:PutBucketOwnershipControls +// permission is required. By default, ObjectOwnership is set to +// BucketOWnerEnforced and ACLs are disabled. We recommend keeping ACLs disabled, +// except in uncommon use cases where you must control access for each object +// individually. If you want to change the ObjectOwnership setting, you can use +// the x-amz-object-ownership header in your CreateBucket request to set the +// ObjectOwnership setting of your choice. For more information about S3 Object +// Ownership, see Controlling object ownership (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) +// in the Amazon S3 User Guide. +// - S3 Block Public Access - If your specific use case requires granting public +// access to your S3 resources, you can disable Block Public Access. You can create +// a new bucket with Block Public Access enabled, then separately call the +// DeletePublicAccessBlock (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeletePublicAccessBlock.html) +// API. To use this operation, you must have the s3:PutBucketPublicAccessBlock +// permission. By default, all Block Public Access settings are enabled for new +// buckets. To avoid inadvertent exposure of your resources, we recommend keeping +// the S3 Block Public Access settings enabled. For more information about S3 Block +// Public Access, see Blocking public access to your Amazon S3 storage (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) +// in the Amazon S3 User Guide. // -// * Specify a canned ACL using the -// x-amz-acl request header. Amazon S3 supports a set of predefined ACLs, known as -// canned ACLs. Each canned ACL has a predefined set of grantees and permissions. -// For more information, see Canned ACL -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL). -// -// * -// Specify access permissions explicitly using the x-amz-grant-read, -// x-amz-grant-write, x-amz-grant-read-acp, x-amz-grant-write-acp, and -// x-amz-grant-full-control headers. These headers map to the set of permissions -// Amazon S3 supports in an ACL. For more information, see Access control list -// (ACL) overview -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html). You -// specify each grantee as a type=value pair, where the type is one of the -// following: -// -// * id – if the value specified is the canonical user ID of an Amazon -// Web Services account -// -// * uri – if you are granting permissions to a predefined -// group -// -// * emailAddress – if the value specified is the email address of an Amazon -// Web Services account Using email addresses to specify a grantee is only -// supported in the following Amazon Web Services Regions: -// -// * US East (N. -// Virginia) -// -// * US West (N. California) -// -// * US West (Oregon) -// -// * Asia Pacific -// (Singapore) -// -// * Asia Pacific (Sydney) -// -// * Asia Pacific (Tokyo) -// -// * Europe -// (Ireland) -// -// * South America (São Paulo) -// -// For a list of all the Amazon S3 -// supported Regions and endpoints, see Regions and Endpoints -// (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the -// Amazon Web Services General Reference. -// -// For example, the following -// x-amz-grant-read header grants the Amazon Web Services accounts identified by -// account IDs permissions to read object data and its metadata: x-amz-grant-read: -// id="11112222333", id="444455556666" -// -// You can use either a canned ACL or specify -// access permissions explicitly. You cannot do both. Permissions In addition to -// s3:CreateBucket, the following permissions are required when your CreateBucket -// includes specific headers: -// -// * ACLs - If your CreateBucket request specifies ACL -// permissions and the ACL is public-read, public-read-write, authenticated-read, -// or if you specify access permissions explicitly through any other ACL, both -// s3:CreateBucket and s3:PutBucketAcl permissions are needed. If the ACL the -// CreateBucket request is private or doesn't specify any ACLs, only -// s3:CreateBucket permission is needed. -// -// * Object Lock - If -// ObjectLockEnabledForBucket is set to true in your CreateBucket request, -// s3:PutBucketObjectLockConfiguration and s3:PutBucketVersioning permissions are -// required. -// -// * S3 Object Ownership - If your CreateBucket request includes the the -// x-amz-object-ownership header, s3:PutBucketOwnershipControls permission is -// required. -// -// The following operations are related to CreateBucket: -// -// * PutObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) -// -// * -// DeleteBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) +// If your CreateBucket request sets BucketOwnerEnforced for Amazon S3 Object +// Ownership and specifies a bucket ACL that provides access to an external Amazon +// Web Services account, your request fails with a 400 error and returns the +// InvalidBucketAcLWithObjectOwnership error code. For more information, see +// Setting Object Ownership on an existing bucket (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-ownership-existing-bucket.html) +// in the Amazon S3 User Guide. The following operations are related to +// CreateBucket : +// - PutObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) +// - DeleteBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) func (c *Client) CreateBucket(ctx context.Context, params *CreateBucketInput, optFns ...func(*Options)) (*CreateBucketOutput, error) { if params == nil { params = &CreateBucketInput{} @@ -216,6 +165,9 @@ func (c *Client) addOperationCreateBucketMiddlewares(stack *middleware.Stack, op if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -243,7 +195,7 @@ func (c *Client) addOperationCreateBucketMiddlewares(stack *middleware.Stack, op if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -255,6 +207,9 @@ func (c *Client) addOperationCreateBucketMiddlewares(stack *middleware.Stack, op if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addCreateBucketResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpCreateBucketValidationMiddleware(stack); err != nil { return err } @@ -264,6 +219,9 @@ func (c *Client) addOperationCreateBucketMiddlewares(stack *middleware.Stack, op if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addCreateBucketUpdateEndpoint(stack, options); err != nil { return err } @@ -279,9 +237,22 @@ func (c *Client) addOperationCreateBucketMiddlewares(stack *middleware.Stack, op if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *CreateBucketInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opCreateBucket(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -316,3 +287,141 @@ func addCreateBucketUpdateEndpoint(stack *middleware.Stack, options Options) err DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opCreateBucketResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opCreateBucketResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opCreateBucketResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*CreateBucketInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + params.DisableAccessPoints = ptr.Bool(true) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addCreateBucketResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opCreateBucketResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CreateMultipartUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CreateMultipartUpload.go index 825feebd2..2831c54c7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CreateMultipartUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_CreateMultipartUpload.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "time" @@ -16,223 +22,163 @@ import ( // This action initiates a multipart upload and returns an upload ID. This upload // ID is used to associate all of the parts in the specific multipart upload. You // specify this upload ID in each of your subsequent upload part requests (see -// UploadPart -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html)). You also -// include this upload ID in the final request to either complete or abort the -// multipart upload request. For more information about multipart uploads, see -// Multipart Upload Overview -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html). If you have -// configured a lifecycle rule to abort incomplete multipart uploads, the upload -// must complete within the number of days specified in the bucket lifecycle -// configuration. Otherwise, the incomplete multipart upload becomes eligible for -// an abort action and Amazon S3 aborts the multipart upload. For more information, -// see Aborting Incomplete Multipart Uploads Using a Bucket Lifecycle Policy -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config). -// For information about the permissions required to use the multipart upload API, -// see Multipart Upload and Permissions -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html). For -// request signing, multipart upload is just a series of regular requests. You -// initiate a multipart upload, send one or more requests to upload parts, and then -// complete the multipart upload process. You sign each request individually. There -// is nothing special about signing multipart upload requests. For more information -// about signing, see Authenticating Requests (Amazon Web Services Signature -// Version 4) -// (https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html). -// After you initiate a multipart upload and upload one or more parts, to stop +// UploadPart (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) +// ). You also include this upload ID in the final request to either complete or +// abort the multipart upload request. For more information about multipart +// uploads, see Multipart Upload Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html) +// . If you have configured a lifecycle rule to abort incomplete multipart uploads, +// the upload must complete within the number of days specified in the bucket +// lifecycle configuration. Otherwise, the incomplete multipart upload becomes +// eligible for an abort action and Amazon S3 aborts the multipart upload. For more +// information, see Aborting Incomplete Multipart Uploads Using a Bucket Lifecycle +// Configuration (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config) +// . For information about the permissions required to use the multipart upload +// API, see Multipart Upload and Permissions (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html) +// . For request signing, multipart upload is just a series of regular requests. +// You initiate a multipart upload, send one or more requests to upload parts, and +// then complete the multipart upload process. You sign each request individually. +// There is nothing special about signing multipart upload requests. For more +// information about signing, see Authenticating Requests (Amazon Web Services +// Signature Version 4) (https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) +// . After you initiate a multipart upload and upload one or more parts, to stop // being charged for storing the uploaded parts, you must either complete or abort // the multipart upload. Amazon S3 frees up the space used to store the parts and // stop charging you for storing them only after you either complete or abort a -// multipart upload. You can optionally request server-side encryption. For -// server-side encryption, Amazon S3 encrypts your data as it writes it to disks in -// its data centers and decrypts it when you access it. You can provide your own -// encryption key, or use Amazon Web Services KMS keys or Amazon S3-managed -// encryption keys. If you choose to provide your own encryption key, the request -// headers you provide in UploadPart -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) and -// UploadPartCopy -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) +// multipart upload. Server-side encryption is for data encryption at rest. Amazon +// S3 encrypts your data as it writes it to disks in its data centers and decrypts +// it when you access it. Amazon S3 automatically encrypts all new objects that are +// uploaded to an S3 bucket. When doing a multipart upload, if you don't specify +// encryption information in your request, the encryption setting of the uploaded +// parts is set to the default encryption configuration of the destination bucket. +// By default, all buckets have a base level of encryption configuration that uses +// server-side encryption with Amazon S3 managed keys (SSE-S3). If the destination +// bucket has a default encryption configuration that uses server-side encryption +// with an Key Management Service (KMS) key (SSE-KMS), or a customer-provided +// encryption key (SSE-C), Amazon S3 uses the corresponding KMS key, or a +// customer-provided key to encrypt the uploaded parts. When you perform a +// CreateMultipartUpload operation, if you want to use a different type of +// encryption setting for the uploaded parts, you can request that Amazon S3 +// encrypts the object with a KMS key, an Amazon S3 managed key, or a +// customer-provided key. If the encryption setting in your request is different +// from the default encryption configuration of the destination bucket, the +// encryption setting in your request takes precedence. If you choose to provide +// your own encryption key, the request headers you provide in UploadPart (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) +// and UploadPartCopy (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) // requests must match the headers you used in the request to initiate the upload -// by using CreateMultipartUpload. To perform a multipart upload with encryption -// using an Amazon Web Services KMS key, the requester must have permission to the -// kms:Decrypt and kms:GenerateDataKey* actions on the key. These permissions are -// required because Amazon S3 must decrypt and read data from the encrypted file -// parts before it completes the multipart upload. For more information, see -// Multipart upload API and permissions -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html#mpuAndPermissions) +// by using CreateMultipartUpload . You can request that Amazon S3 save the +// uploaded parts encrypted with server-side encryption with an Amazon S3 managed +// key (SSE-S3), an Key Management Service (KMS) key (SSE-KMS), or a +// customer-provided encryption key (SSE-C). To perform a multipart upload with +// encryption by using an Amazon Web Services KMS key, the requester must have +// permission to the kms:Decrypt and kms:GenerateDataKey* actions on the key. +// These permissions are required because Amazon S3 must decrypt and read data from +// the encrypted file parts before it completes the multipart upload. For more +// information, see Multipart upload API and permissions (https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html#mpuAndPermissions) +// and Protecting data using server-side encryption with Amazon Web Services KMS (https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html) // in the Amazon S3 User Guide. If your Identity and Access Management (IAM) user // or role is in the same Amazon Web Services account as the KMS key, then you must // have these permissions on the key policy. If your IAM user or role belongs to a // different account than the key, then you must have the permissions on both the // key policy and your IAM user or role. For more information, see Protecting Data -// Using Server-Side Encryption -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html). -// Access Permissions When copying an object, you can optionally specify the +// Using Server-Side Encryption (https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html) +// . Access Permissions When copying an object, you can optionally specify the // accounts or groups that should be granted specific permissions on the new -// object. There are two ways to grant the permissions using the request -// headers: -// -// * Specify a canned ACL with the x-amz-acl request header. For more -// information, see Canned ACL -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL). -// -// * -// Specify access permissions explicitly with the x-amz-grant-read, -// x-amz-grant-read-acp, x-amz-grant-write-acp, and x-amz-grant-full-control -// headers. These parameters map to the set of permissions that Amazon S3 supports -// in an ACL. For more information, see Access Control List (ACL) Overview -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html). -// -// You can -// use either a canned ACL or specify access permissions explicitly. You cannot do -// both. Server-Side- Encryption-Specific Request Headers You can optionally tell -// Amazon S3 to encrypt data at rest using server-side encryption. Server-side -// encryption is for data encryption at rest. Amazon S3 encrypts your data as it -// writes it to disks in its data centers and decrypts it when you access it. The -// option you use depends on whether you want to use Amazon Web Services managed -// encryption keys or provide your own encryption key. -// -// * Use encryption keys -// managed by Amazon S3 or customer managed key stored in Amazon Web Services Key -// Management Service (Amazon Web Services KMS) – If you want Amazon Web Services -// to manage the keys used to encrypt data, specify the following headers in the -// request. -// -// * x-amz-server-side-encryption -// -// * -// x-amz-server-side-encryption-aws-kms-key-id -// -// * -// x-amz-server-side-encryption-context -// -// If you specify -// x-amz-server-side-encryption:aws:kms, but don't provide -// x-amz-server-side-encryption-aws-kms-key-id, Amazon S3 uses the Amazon Web -// Services managed key in Amazon Web Services KMS to protect the data. All GET and -// PUT requests for an object protected by Amazon Web Services KMS fail if you -// don't make them with SSL or by using SigV4. For more information about -// server-side encryption with KMS key (SSE-KMS), see Protecting Data Using -// Server-Side Encryption with KMS keys -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html). -// -// * -// Use customer-provided encryption keys – If you want to manage your own -// encryption keys, provide all the following headers in the request. -// -// * -// x-amz-server-side-encryption-customer-algorithm -// -// * -// x-amz-server-side-encryption-customer-key -// -// * -// x-amz-server-side-encryption-customer-key-MD5 -// -// For more information about -// server-side encryption with KMS keys (SSE-KMS), see Protecting Data Using -// Server-Side Encryption with KMS keys -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html). -// -// Access-Control-List -// (ACL)-Specific Request Headers You also can use the following access -// control–related headers with this operation. By default, all objects are -// private. Only the owner has full access control. When adding a new object, you -// can grant permissions to individual Amazon Web Services accounts or to -// predefined groups defined by Amazon S3. These permissions are then added to the -// access control list (ACL) on the object. For more information, see Using ACLs -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/S3_ACLs_UsingACLs.html). With -// this operation, you can grant access permissions using one of the following two -// methods: -// -// * Specify a canned ACL (x-amz-acl) — Amazon S3 supports a set of -// predefined ACLs, known as canned ACLs. Each canned ACL has a predefined set of -// grantees and permissions. For more information, see Canned ACL -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL). -// -// * -// Specify access permissions explicitly — To explicitly grant access permissions -// to specific Amazon Web Services accounts or groups, use the following headers. -// Each header maps to specific permissions that Amazon S3 supports in an ACL. For -// more information, see Access Control List (ACL) Overview -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html). In the -// header, you specify a list of grantees who get the specific permission. To grant -// permissions explicitly, use: -// -// * x-amz-grant-read -// -// * x-amz-grant-write -// -// * -// x-amz-grant-read-acp -// -// * x-amz-grant-write-acp -// -// * x-amz-grant-full-control -// -// You -// specify each grantee as a type=value pair, where the type is one of the -// following: -// -// * id – if the value specified is the canonical user ID of an Amazon -// Web Services account -// -// * uri – if you are granting permissions to a predefined -// group -// -// * emailAddress – if the value specified is the email address of an Amazon -// Web Services account Using email addresses to specify a grantee is only -// supported in the following Amazon Web Services Regions: -// -// * US East (N. -// Virginia) -// -// * US West (N. California) -// -// * US West (Oregon) -// -// * Asia Pacific -// (Singapore) -// -// * Asia Pacific (Sydney) -// -// * Asia Pacific (Tokyo) -// -// * Europe -// (Ireland) -// -// * South America (São Paulo) -// -// For a list of all the Amazon S3 -// supported Regions and endpoints, see Regions and Endpoints -// (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the -// Amazon Web Services General Reference. -// -// For example, the following -// x-amz-grant-read header grants the Amazon Web Services accounts identified by -// account IDs permissions to read object data and its metadata: x-amz-grant-read: -// id="11112222333", id="444455556666" -// -// The following operations are related to -// CreateMultipartUpload: -// -// * UploadPart -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) -// -// * -// CompleteMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) -// -// * -// AbortMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) -// -// * -// ListParts -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) -// -// * -// ListMultipartUploads -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) +// object. There are two ways to grant the permissions using the request headers: +// - Specify a canned ACL with the x-amz-acl request header. For more +// information, see Canned ACL (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL) +// . +// - Specify access permissions explicitly with the x-amz-grant-read , +// x-amz-grant-read-acp , x-amz-grant-write-acp , and x-amz-grant-full-control +// headers. These parameters map to the set of permissions that Amazon S3 supports +// in an ACL. For more information, see Access Control List (ACL) Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html) +// . +// +// You can use either a canned ACL or specify access permissions explicitly. You +// cannot do both. Server-Side- Encryption-Specific Request Headers Amazon S3 +// encrypts data by using server-side encryption with an Amazon S3 managed key +// (SSE-S3) by default. Server-side encryption is for data encryption at rest. +// Amazon S3 encrypts your data as it writes it to disks in its data centers and +// decrypts it when you access it. You can request that Amazon S3 encrypts data at +// rest by using server-side encryption with other key options. The option you use +// depends on whether you want to use KMS keys (SSE-KMS) or provide your own +// encryption keys (SSE-C). +// - Use KMS keys (SSE-KMS) that include the Amazon Web Services managed key ( +// aws/s3 ) and KMS customer managed keys stored in Key Management Service (KMS) +// – If you want Amazon Web Services to manage the keys used to encrypt data, +// specify the following headers in the request. +// - x-amz-server-side-encryption +// - x-amz-server-side-encryption-aws-kms-key-id +// - x-amz-server-side-encryption-context If you specify +// x-amz-server-side-encryption:aws:kms , but don't provide +// x-amz-server-side-encryption-aws-kms-key-id , Amazon S3 uses the Amazon Web +// Services managed key ( aws/s3 key) in KMS to protect the data. All GET and PUT +// requests for an object protected by KMS fail if you don't make them by using +// Secure Sockets Layer (SSL), Transport Layer Security (TLS), or Signature Version +// 4. For more information about server-side encryption with KMS keys (SSE-KMS), +// see Protecting Data Using Server-Side Encryption with KMS keys (https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html) +// . +// - Use customer-provided encryption keys (SSE-C) – If you want to manage your +// own encryption keys, provide all the following headers in the request. +// - x-amz-server-side-encryption-customer-algorithm +// - x-amz-server-side-encryption-customer-key +// - x-amz-server-side-encryption-customer-key-MD5 For more information about +// server-side encryption with customer-provided encryption keys (SSE-C), see +// Protecting data using server-side encryption with customer-provided encryption +// keys (SSE-C) (https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html) +// . +// +// Access-Control-List (ACL)-Specific Request Headers You also can use the +// following access control–related headers with this operation. By default, all +// objects are private. Only the owner has full access control. When adding a new +// object, you can grant permissions to individual Amazon Web Services accounts or +// to predefined groups defined by Amazon S3. These permissions are then added to +// the access control list (ACL) on the object. For more information, see Using +// ACLs (https://docs.aws.amazon.com/AmazonS3/latest/dev/S3_ACLs_UsingACLs.html) . +// With this operation, you can grant access permissions using one of the following +// two methods: +// - Specify a canned ACL ( x-amz-acl ) — Amazon S3 supports a set of predefined +// ACLs, known as canned ACLs. Each canned ACL has a predefined set of grantees and +// permissions. For more information, see Canned ACL (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL) +// . +// - Specify access permissions explicitly — To explicitly grant access +// permissions to specific Amazon Web Services accounts or groups, use the +// following headers. Each header maps to specific permissions that Amazon S3 +// supports in an ACL. For more information, see Access Control List (ACL) +// Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html) . +// In the header, you specify a list of grantees who get the specific permission. +// To grant permissions explicitly, use: +// - x-amz-grant-read +// - x-amz-grant-write +// - x-amz-grant-read-acp +// - x-amz-grant-write-acp +// - x-amz-grant-full-control You specify each grantee as a type=value pair, +// where the type is one of the following: +// - id – if the value specified is the canonical user ID of an Amazon Web +// Services account +// - uri – if you are granting permissions to a predefined group +// - emailAddress – if the value specified is the email address of an Amazon Web +// Services account Using email addresses to specify a grantee is only supported in +// the following Amazon Web Services Regions: +// - US East (N. Virginia) +// - US West (N. California) +// - US West (Oregon) +// - Asia Pacific (Singapore) +// - Asia Pacific (Sydney) +// - Asia Pacific (Tokyo) +// - Europe (Ireland) +// - South America (São Paulo) For a list of all the Amazon S3 supported Regions +// and endpoints, see Regions and Endpoints (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) +// in the Amazon Web Services General Reference. For example, the following +// x-amz-grant-read header grants the Amazon Web Services accounts identified by +// account IDs permissions to read object data and its metadata: +// x-amz-grant-read: id="11112222333", id="444455556666" +// +// The following operations are related to CreateMultipartUpload : +// - UploadPart (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) +// - CompleteMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) +// - AbortMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) +// - ListParts (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) +// - ListMultipartUploads (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) func (c *Client) CreateMultipartUpload(ctx context.Context, params *CreateMultipartUploadInput, optFns ...func(*Options)) (*CreateMultipartUploadOutput, error) { if params == nil { params = &CreateMultipartUploadInput{} @@ -256,17 +202,15 @@ type CreateMultipartUploadInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -276,23 +220,22 @@ type CreateMultipartUploadInput struct { // This member is required. Key *string - // The canned ACL to apply to the object. This action is not supported by Amazon S3 - // on Outposts. + // The canned ACL to apply to the object. This action is not supported by Amazon + // S3 on Outposts. ACL types.ObjectCannedACL // Specifies whether Amazon S3 should use an S3 Bucket Key for object encryption - // with server-side encryption using AWS KMS (SSE-KMS). Setting this header to true - // causes Amazon S3 to use an S3 Bucket Key for object encryption with SSE-KMS. - // Specifying this header with an object action doesn’t affect bucket-level - // settings for S3 Bucket Key. + // with server-side encryption using Key Management Service (KMS) keys (SSE-KMS). + // Setting this header to true causes Amazon S3 to use an S3 Bucket Key for object + // encryption with SSE-KMS. Specifying this header with an object action doesn’t + // affect bucket-level settings for S3 Bucket Key. BucketKeyEnabled bool // Specifies caching behavior along the request/reply chain. CacheControl *string - // Indicates the algorithm you want Amazon S3 to use to create the checksum for the - // object. For more information, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Indicates the algorithm you want Amazon S3 to use to create the checksum for + // the object. For more information, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumAlgorithm types.ChecksumAlgorithm @@ -326,8 +269,8 @@ type CreateMultipartUploadInput struct { // supported by Amazon S3 on Outposts. GrantRead *string - // Allows grantee to read the object ACL. This action is not supported by Amazon S3 - // on Outposts. + // Allows grantee to read the object ACL. This action is not supported by Amazon + // S3 on Outposts. GrantReadACP *string // Allows grantee to write the ACL for the applicable object. This action is not @@ -347,10 +290,11 @@ type CreateMultipartUploadInput struct { ObjectLockRetainUntilDate *time.Time // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -375,27 +319,25 @@ type CreateMultipartUploadInput struct { // JSON with the encryption context key-value pairs. SSEKMSEncryptionContext *string - // Specifies the ID of the symmetric customer managed key to use for object - // encryption. All GET and PUT requests for an object protected by Amazon Web - // Services KMS will fail if not made via SSL or using SigV4. For information about - // configuring using any of the officially supported Amazon Web Services SDKs and - // Amazon Web Services CLI, see Specifying the Signature Version in Request - // Authentication - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAWSSDK.html#specify-signature-version) + // Specifies the ID (Key ID, Key ARN, or Key Alias) of the symmetric encryption + // customer managed key to use for object encryption. All GET and PUT requests for + // an object protected by KMS will fail if they're not made via SSL or using SigV4. + // For information about configuring any of the officially supported Amazon Web + // Services SDKs and Amazon Web Services CLI, see Specifying the Signature Version + // in Request Authentication (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAWSSDK.html#specify-signature-version) // in the Amazon S3 User Guide. SSEKMSKeyId *string // The server-side encryption algorithm used when storing this object in Amazon S3 - // (for example, AES256, aws:kms). + // (for example, AES256 , aws:kms ). ServerSideEncryption types.ServerSideEncryption // By default, Amazon S3 uses the STANDARD Storage Class to store newly created // objects. The STANDARD storage class provides high durability and high // availability. Depending on performance needs, you can specify a different // Storage Class. Amazon S3 on Outposts only uses the OUTPOSTS Storage Class. For - // more information, see Storage Classes - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html) in - // the Amazon S3 User Guide. + // more information, see Storage Classes (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html) + // in the Amazon S3 User Guide. StorageClass types.StorageClass // The tag-set for the object. The tag-set must be encoded as URL Query parameters. @@ -411,15 +353,14 @@ type CreateMultipartUploadInput struct { type CreateMultipartUploadOutput struct { - // If the bucket has a lifecycle rule configured with an action to abort incomplete - // multipart uploads and the prefix in the lifecycle rule matches the object name - // in the request, the response includes this header. The header indicates when the - // initiated multipart upload becomes eligible for an abort operation. For more - // information, see Aborting Incomplete Multipart Uploads Using a Bucket Lifecycle - // Policy - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config). - // The response also includes the x-amz-abort-rule-id header that provides the ID - // of the lifecycle configuration rule that defines this action. + // If the bucket has a lifecycle rule configured with an action to abort + // incomplete multipart uploads and the prefix in the lifecycle rule matches the + // object name in the request, the response includes this header. The header + // indicates when the initiated multipart upload becomes eligible for an abort + // operation. For more information, see Aborting Incomplete Multipart Uploads + // Using a Bucket Lifecycle Configuration (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config) + // . The response also includes the x-amz-abort-rule-id header that provides the + // ID of the lifecycle configuration rule that defines this action. AbortDate *time.Time // This header is returned along with the x-amz-abort-date header. It identifies @@ -434,21 +375,19 @@ type CreateMultipartUploadOutput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. Bucket *string // Indicates whether the multipart upload uses an S3 Bucket Key for server-side - // encryption with Amazon Web Services KMS (SSE-KMS). + // encryption with Key Management Service (KMS) keys (SSE-KMS). BucketKeyEnabled bool // The algorithm that was used to create a checksum of the object. @@ -461,13 +400,14 @@ type CreateMultipartUploadOutput struct { // request. RequestCharged types.RequestCharged - // If server-side encryption with a customer-provided encryption key was requested, - // the response will include this header confirming the encryption algorithm used. + // If server-side encryption with a customer-provided encryption key was + // requested, the response will include this header confirming the encryption + // algorithm used. SSECustomerAlgorithm *string - // If server-side encryption with a customer-provided encryption key was requested, - // the response will include this header to provide round-trip message integrity - // verification of the customer-provided encryption key. + // If server-side encryption with a customer-provided encryption key was + // requested, the response will include this header to provide round-trip message + // integrity verification of the customer-provided encryption key. SSECustomerKeyMD5 *string // If present, specifies the Amazon Web Services KMS Encryption Context to use for @@ -475,13 +415,12 @@ type CreateMultipartUploadOutput struct { // holding JSON with the encryption context key-value pairs. SSEKMSEncryptionContext *string - // If present, specifies the ID of the Amazon Web Services Key Management Service - // (Amazon Web Services KMS) symmetric customer managed key that was used for the - // object. + // If present, specifies the ID of the Key Management Service (KMS) symmetric + // encryption customer managed key that was used for the object. SSEKMSKeyId *string // The server-side encryption algorithm used when storing this object in Amazon S3 - // (for example, AES256, aws:kms). + // (for example, AES256 , aws:kms ). ServerSideEncryption types.ServerSideEncryption // ID for the initiated multipart upload. @@ -502,6 +441,9 @@ func (c *Client) addOperationCreateMultipartUploadMiddlewares(stack *middleware. if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -529,7 +471,7 @@ func (c *Client) addOperationCreateMultipartUploadMiddlewares(stack *middleware. if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -541,6 +483,9 @@ func (c *Client) addOperationCreateMultipartUploadMiddlewares(stack *middleware. if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addCreateMultipartUploadResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpCreateMultipartUploadValidationMiddleware(stack); err != nil { return err } @@ -550,6 +495,9 @@ func (c *Client) addOperationCreateMultipartUploadMiddlewares(stack *middleware. if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addCreateMultipartUploadUpdateEndpoint(stack, options); err != nil { return err } @@ -565,9 +513,22 @@ func (c *Client) addOperationCreateMultipartUploadMiddlewares(stack *middleware. if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *CreateMultipartUploadInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opCreateMultipartUpload(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -602,3 +563,139 @@ func addCreateMultipartUploadUpdateEndpoint(stack *middleware.Stack, options Opt DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opCreateMultipartUploadResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opCreateMultipartUploadResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opCreateMultipartUploadResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*CreateMultipartUploadInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addCreateMultipartUploadResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opCreateMultipartUploadResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucket.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucket.go index 6bfb43c22..ba163363b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucket.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucket.go @@ -4,23 +4,24 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Deletes the S3 bucket. All objects (including all object versions and delete // markers) in the bucket must be deleted before the bucket itself can be deleted. -// Related Resources -// -// * CreateBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) -// -// * -// DeleteObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) +// The following operations are related to DeleteBucket : +// - CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) +// - DeleteObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) func (c *Client) DeleteBucket(ctx context.Context, params *DeleteBucketInput, optFns ...func(*Options)) (*DeleteBucketOutput, error) { if params == nil { params = &DeleteBucketInput{} @@ -67,6 +68,9 @@ func (c *Client) addOperationDeleteBucketMiddlewares(stack *middleware.Stack, op if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -94,7 +98,7 @@ func (c *Client) addOperationDeleteBucketMiddlewares(stack *middleware.Stack, op if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -106,6 +110,9 @@ func (c *Client) addOperationDeleteBucketMiddlewares(stack *middleware.Stack, op if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteBucketResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteBucketValidationMiddleware(stack); err != nil { return err } @@ -115,6 +122,9 @@ func (c *Client) addOperationDeleteBucketMiddlewares(stack *middleware.Stack, op if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteBucketUpdateEndpoint(stack, options); err != nil { return err } @@ -130,9 +140,22 @@ func (c *Client) addOperationDeleteBucketMiddlewares(stack *middleware.Stack, op if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteBucketInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteBucket(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -198,3 +221,139 @@ func addDeleteBucketPayloadAsUnsigned(stack *middleware.Stack, options Options) v4.RemoveComputePayloadSHA256Middleware(stack) return v4.AddUnsignedPayloadMiddleware(stack) } + +type opDeleteBucketResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteBucketResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteBucketResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteBucketInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteBucketResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteBucketResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketAnalyticsConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketAnalyticsConfiguration.go index e016d9763..12d12e6cd 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketAnalyticsConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketAnalyticsConfiguration.go @@ -4,38 +4,32 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Deletes an analytics configuration for the bucket (specified by the analytics // configuration ID). To use this operation, you must have permissions to perform -// the s3:PutAnalyticsConfiguration action. The bucket owner has this permission by -// default. The bucket owner can grant this permission to others. For more +// the s3:PutAnalyticsConfiguration action. The bucket owner has this permission +// by default. The bucket owner can grant this permission to others. For more // information about permissions, see Permissions Related to Bucket Subresource -// Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// For information about the Amazon S3 analytics feature, see Amazon S3 Analytics – -// Storage Class Analysis -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/analytics-storage-class.html). -// The following operations are related to DeleteBucketAnalyticsConfiguration: -// -// * -// GetBucketAnalyticsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAnalyticsConfiguration.html) -// -// * -// ListBucketAnalyticsConfigurations -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketAnalyticsConfigurations.html) -// -// * -// PutBucketAnalyticsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAnalyticsConfiguration.html) +// Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . For information about the Amazon S3 analytics feature, see Amazon S3 +// Analytics – Storage Class Analysis (https://docs.aws.amazon.com/AmazonS3/latest/dev/analytics-storage-class.html) +// . The following operations are related to DeleteBucketAnalyticsConfiguration : +// - GetBucketAnalyticsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAnalyticsConfiguration.html) +// - ListBucketAnalyticsConfigurations (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketAnalyticsConfigurations.html) +// - PutBucketAnalyticsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAnalyticsConfiguration.html) func (c *Client) DeleteBucketAnalyticsConfiguration(ctx context.Context, params *DeleteBucketAnalyticsConfigurationInput, optFns ...func(*Options)) (*DeleteBucketAnalyticsConfigurationOutput, error) { if params == nil { params = &DeleteBucketAnalyticsConfigurationInput{} @@ -87,6 +81,9 @@ func (c *Client) addOperationDeleteBucketAnalyticsConfigurationMiddlewares(stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -114,7 +111,7 @@ func (c *Client) addOperationDeleteBucketAnalyticsConfigurationMiddlewares(stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -126,6 +123,9 @@ func (c *Client) addOperationDeleteBucketAnalyticsConfigurationMiddlewares(stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteBucketAnalyticsConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteBucketAnalyticsConfigurationValidationMiddleware(stack); err != nil { return err } @@ -135,6 +135,9 @@ func (c *Client) addOperationDeleteBucketAnalyticsConfigurationMiddlewares(stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteBucketAnalyticsConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -150,9 +153,22 @@ func (c *Client) addOperationDeleteBucketAnalyticsConfigurationMiddlewares(stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteBucketAnalyticsConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteBucketAnalyticsConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -187,3 +203,139 @@ func addDeleteBucketAnalyticsConfigurationUpdateEndpoint(stack *middleware.Stack DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeleteBucketAnalyticsConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteBucketAnalyticsConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteBucketAnalyticsConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteBucketAnalyticsConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteBucketAnalyticsConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteBucketAnalyticsConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketCors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketCors.go index 79045abe2..ae90a9067 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketCors.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketCors.go @@ -4,9 +4,15 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -14,16 +20,10 @@ import ( // Deletes the cors configuration information set for the bucket. To use this // operation, you must have permission to perform the s3:PutBucketCORS action. The // bucket owner has this permission by default and can grant this permission to -// others. For information about cors, see Enabling Cross-Origin Resource Sharing -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html) in the Amazon S3 -// User Guide. Related Resources: -// -// * PutBucketCors -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html) -// -// * -// RESTOPTIONSobject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTOPTIONSobject.html) +// others. For information about cors , see Enabling Cross-Origin Resource Sharing (https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html) +// in the Amazon S3 User Guide. Related Resources +// - PutBucketCors (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html) +// - RESTOPTIONSobject (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTOPTIONSobject.html) func (c *Client) DeleteBucketCors(ctx context.Context, params *DeleteBucketCorsInput, optFns ...func(*Options)) (*DeleteBucketCorsOutput, error) { if params == nil { params = &DeleteBucketCorsInput{} @@ -70,6 +70,9 @@ func (c *Client) addOperationDeleteBucketCorsMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -97,7 +100,7 @@ func (c *Client) addOperationDeleteBucketCorsMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -109,6 +112,9 @@ func (c *Client) addOperationDeleteBucketCorsMiddlewares(stack *middleware.Stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteBucketCorsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteBucketCorsValidationMiddleware(stack); err != nil { return err } @@ -118,6 +124,9 @@ func (c *Client) addOperationDeleteBucketCorsMiddlewares(stack *middleware.Stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteBucketCorsUpdateEndpoint(stack, options); err != nil { return err } @@ -133,9 +142,22 @@ func (c *Client) addOperationDeleteBucketCorsMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteBucketCorsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteBucketCors(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -170,3 +192,139 @@ func addDeleteBucketCorsUpdateEndpoint(stack *middleware.Stack, options Options) DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeleteBucketCorsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteBucketCorsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteBucketCorsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteBucketCorsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteBucketCorsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteBucketCorsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketEncryption.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketEncryption.go index 9c3201f6d..754ae6a59 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketEncryption.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketEncryption.go @@ -4,33 +4,33 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// This implementation of the DELETE action removes default encryption from the -// bucket. For information about the Amazon S3 default encryption feature, see -// Amazon S3 Default Bucket Encryption -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html) in the -// Amazon S3 User Guide. To use this operation, you must have permissions to +// This implementation of the DELETE action resets the default encryption for the +// bucket as server-side encryption with Amazon S3 managed keys (SSE-S3). For +// information about the bucket default encryption feature, see Amazon S3 Bucket +// Default Encryption (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html) +// in the Amazon S3 User Guide. To use this operation, you must have permissions to // perform the s3:PutEncryptionConfiguration action. The bucket owner has this // permission by default. The bucket owner can grant this permission to others. For // more information about permissions, see Permissions Related to Bucket -// Subresource Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) -// in the Amazon S3 User Guide. Related Resources -// -// * PutBucketEncryption -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) -// -// * -// GetBucketEncryption -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html) +// Subresource Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// in the Amazon S3 User Guide. The following operations are related to +// DeleteBucketEncryption : +// - PutBucketEncryption (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) +// - GetBucketEncryption (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html) func (c *Client) DeleteBucketEncryption(ctx context.Context, params *DeleteBucketEncryptionInput, optFns ...func(*Options)) (*DeleteBucketEncryptionOutput, error) { if params == nil { params = &DeleteBucketEncryptionInput{} @@ -78,6 +78,9 @@ func (c *Client) addOperationDeleteBucketEncryptionMiddlewares(stack *middleware if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -105,7 +108,7 @@ func (c *Client) addOperationDeleteBucketEncryptionMiddlewares(stack *middleware if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -117,6 +120,9 @@ func (c *Client) addOperationDeleteBucketEncryptionMiddlewares(stack *middleware if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteBucketEncryptionResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteBucketEncryptionValidationMiddleware(stack); err != nil { return err } @@ -126,6 +132,9 @@ func (c *Client) addOperationDeleteBucketEncryptionMiddlewares(stack *middleware if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteBucketEncryptionUpdateEndpoint(stack, options); err != nil { return err } @@ -141,9 +150,22 @@ func (c *Client) addOperationDeleteBucketEncryptionMiddlewares(stack *middleware if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteBucketEncryptionInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteBucketEncryption(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -178,3 +200,139 @@ func addDeleteBucketEncryptionUpdateEndpoint(stack *middleware.Stack, options Op DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeleteBucketEncryptionResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteBucketEncryptionResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteBucketEncryptionResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteBucketEncryptionInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteBucketEncryptionResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteBucketEncryptionResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketIntelligentTieringConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketIntelligentTieringConfiguration.go index 139dd78a0..e71e5fb8c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketIntelligentTieringConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketIntelligentTieringConfiguration.go @@ -4,9 +4,15 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -24,21 +30,11 @@ import ( // monitored and not eligible for auto-tiering. Smaller objects can be stored, but // they are always charged at the Frequent Access tier rates in the S3 // Intelligent-Tiering storage class. For more information, see Storage class for -// automatically optimizing frequently and infrequently accessed objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access). -// Operations related to DeleteBucketIntelligentTieringConfiguration include: -// -// * -// GetBucketIntelligentTieringConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketIntelligentTieringConfiguration.html) -// -// * -// PutBucketIntelligentTieringConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketIntelligentTieringConfiguration.html) -// -// * -// ListBucketIntelligentTieringConfigurations -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketIntelligentTieringConfigurations.html) +// automatically optimizing frequently and infrequently accessed objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access) +// . Operations related to DeleteBucketIntelligentTieringConfiguration include: +// - GetBucketIntelligentTieringConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketIntelligentTieringConfiguration.html) +// - PutBucketIntelligentTieringConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketIntelligentTieringConfiguration.html) +// - ListBucketIntelligentTieringConfigurations (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketIntelligentTieringConfigurations.html) func (c *Client) DeleteBucketIntelligentTieringConfiguration(ctx context.Context, params *DeleteBucketIntelligentTieringConfigurationInput, optFns ...func(*Options)) (*DeleteBucketIntelligentTieringConfigurationOutput, error) { if params == nil { params = &DeleteBucketIntelligentTieringConfigurationInput{} @@ -86,6 +82,9 @@ func (c *Client) addOperationDeleteBucketIntelligentTieringConfigurationMiddlewa if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -113,7 +112,7 @@ func (c *Client) addOperationDeleteBucketIntelligentTieringConfigurationMiddlewa if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -125,6 +124,9 @@ func (c *Client) addOperationDeleteBucketIntelligentTieringConfigurationMiddlewa if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteBucketIntelligentTieringConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteBucketIntelligentTieringConfigurationValidationMiddleware(stack); err != nil { return err } @@ -134,6 +136,9 @@ func (c *Client) addOperationDeleteBucketIntelligentTieringConfigurationMiddlewa if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteBucketIntelligentTieringConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -149,9 +154,22 @@ func (c *Client) addOperationDeleteBucketIntelligentTieringConfigurationMiddlewa if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteBucketIntelligentTieringConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteBucketIntelligentTieringConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -186,3 +204,139 @@ func addDeleteBucketIntelligentTieringConfigurationUpdateEndpoint(stack *middlew DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeleteBucketIntelligentTieringConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteBucketIntelligentTieringConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteBucketIntelligentTieringConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteBucketIntelligentTieringConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteBucketIntelligentTieringConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteBucketIntelligentTieringConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketInventoryConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketInventoryConfiguration.go index 32fe81f12..4788ce85c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketInventoryConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketInventoryConfiguration.go @@ -4,9 +4,15 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -16,25 +22,13 @@ import ( // s3:PutInventoryConfiguration action. The bucket owner has this permission by // default. The bucket owner can grant this permission to others. For more // information about permissions, see Permissions Related to Bucket Subresource -// Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// For information about the Amazon S3 inventory feature, see Amazon S3 Inventory -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html). -// Operations related to DeleteBucketInventoryConfiguration include: -// -// * -// GetBucketInventoryConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketInventoryConfiguration.html) -// -// * -// PutBucketInventoryConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketInventoryConfiguration.html) -// -// * -// ListBucketInventoryConfigurations -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketInventoryConfigurations.html) +// Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . For information about the Amazon S3 inventory feature, see Amazon S3 Inventory (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html) +// . Operations related to DeleteBucketInventoryConfiguration include: +// - GetBucketInventoryConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketInventoryConfiguration.html) +// - PutBucketInventoryConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketInventoryConfiguration.html) +// - ListBucketInventoryConfigurations (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketInventoryConfigurations.html) func (c *Client) DeleteBucketInventoryConfiguration(ctx context.Context, params *DeleteBucketInventoryConfigurationInput, optFns ...func(*Options)) (*DeleteBucketInventoryConfigurationOutput, error) { if params == nil { params = &DeleteBucketInventoryConfigurationInput{} @@ -86,6 +80,9 @@ func (c *Client) addOperationDeleteBucketInventoryConfigurationMiddlewares(stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -113,7 +110,7 @@ func (c *Client) addOperationDeleteBucketInventoryConfigurationMiddlewares(stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -125,6 +122,9 @@ func (c *Client) addOperationDeleteBucketInventoryConfigurationMiddlewares(stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteBucketInventoryConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteBucketInventoryConfigurationValidationMiddleware(stack); err != nil { return err } @@ -134,6 +134,9 @@ func (c *Client) addOperationDeleteBucketInventoryConfigurationMiddlewares(stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteBucketInventoryConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -149,9 +152,22 @@ func (c *Client) addOperationDeleteBucketInventoryConfigurationMiddlewares(stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteBucketInventoryConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteBucketInventoryConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -186,3 +202,139 @@ func addDeleteBucketInventoryConfigurationUpdateEndpoint(stack *middleware.Stack DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeleteBucketInventoryConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteBucketInventoryConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteBucketInventoryConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteBucketInventoryConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteBucketInventoryConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteBucketInventoryConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketLifecycle.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketLifecycle.go index c110bfb44..f265ec365 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketLifecycle.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketLifecycle.go @@ -4,32 +4,32 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Deletes the lifecycle configuration from the specified bucket. Amazon S3 removes -// all the lifecycle configuration rules in the lifecycle subresource associated -// with the bucket. Your objects never expire, and Amazon S3 no longer +// Deletes the lifecycle configuration from the specified bucket. Amazon S3 +// removes all the lifecycle configuration rules in the lifecycle subresource +// associated with the bucket. Your objects never expire, and Amazon S3 no longer // automatically deletes any objects on the basis of rules contained in the deleted // lifecycle configuration. To use this operation, you must have permission to // perform the s3:PutLifecycleConfiguration action. By default, the bucket owner // has this permission and the bucket owner can grant this permission to others. // There is usually some time lag before lifecycle configuration deletion is fully // propagated to all the Amazon S3 systems. For more information about the object -// expiration, see Elements to Describe Lifecycle Actions -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html#intro-lifecycle-rules-actions). -// Related actions include: -// -// * PutBucketLifecycleConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html) -// -// * -// GetBucketLifecycleConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html) +// expiration, see Elements to Describe Lifecycle Actions (https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html#intro-lifecycle-rules-actions) +// . Related actions include: +// - PutBucketLifecycleConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html) +// - GetBucketLifecycleConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html) func (c *Client) DeleteBucketLifecycle(ctx context.Context, params *DeleteBucketLifecycleInput, optFns ...func(*Options)) (*DeleteBucketLifecycleOutput, error) { if params == nil { params = &DeleteBucketLifecycleInput{} @@ -76,6 +76,9 @@ func (c *Client) addOperationDeleteBucketLifecycleMiddlewares(stack *middleware. if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -103,7 +106,7 @@ func (c *Client) addOperationDeleteBucketLifecycleMiddlewares(stack *middleware. if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -115,6 +118,9 @@ func (c *Client) addOperationDeleteBucketLifecycleMiddlewares(stack *middleware. if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteBucketLifecycleResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteBucketLifecycleValidationMiddleware(stack); err != nil { return err } @@ -124,6 +130,9 @@ func (c *Client) addOperationDeleteBucketLifecycleMiddlewares(stack *middleware. if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteBucketLifecycleUpdateEndpoint(stack, options); err != nil { return err } @@ -139,9 +148,22 @@ func (c *Client) addOperationDeleteBucketLifecycleMiddlewares(stack *middleware. if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteBucketLifecycleInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteBucketLifecycle(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -176,3 +198,139 @@ func addDeleteBucketLifecycleUpdateEndpoint(stack *middleware.Stack, options Opt DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeleteBucketLifecycleResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteBucketLifecycleResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteBucketLifecycleResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteBucketLifecycleInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteBucketLifecycleResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteBucketLifecycleResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketMetricsConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketMetricsConfiguration.go index cc08f04b7..51e57ca70 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketMetricsConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketMetricsConfiguration.go @@ -4,9 +4,15 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -17,30 +23,15 @@ import ( // permissions to perform the s3:PutMetricsConfiguration action. The bucket owner // has this permission by default. The bucket owner can grant this permission to // others. For more information about permissions, see Permissions Related to -// Bucket Subresource Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// For information about CloudWatch request metrics for Amazon S3, see Monitoring -// Metrics with Amazon CloudWatch -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html). -// The following operations are related to DeleteBucketMetricsConfiguration: -// -// * -// GetBucketMetricsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html) -// -// * -// PutBucketMetricsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html) -// -// * -// ListBucketMetricsConfigurations -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html) -// -// * -// Monitoring Metrics with Amazon CloudWatch -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html) +// Bucket Subresource Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . For information about CloudWatch request metrics for Amazon S3, see +// Monitoring Metrics with Amazon CloudWatch (https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html) +// . The following operations are related to DeleteBucketMetricsConfiguration : +// - GetBucketMetricsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html) +// - PutBucketMetricsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html) +// - ListBucketMetricsConfigurations (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html) +// - Monitoring Metrics with Amazon CloudWatch (https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html) func (c *Client) DeleteBucketMetricsConfiguration(ctx context.Context, params *DeleteBucketMetricsConfigurationInput, optFns ...func(*Options)) (*DeleteBucketMetricsConfigurationOutput, error) { if params == nil { params = &DeleteBucketMetricsConfigurationInput{} @@ -63,7 +54,8 @@ type DeleteBucketMetricsConfigurationInput struct { // This member is required. Bucket *string - // The ID used to identify the metrics configuration. + // The ID used to identify the metrics configuration. The ID has a 64 character + // limit and can only contain letters, numbers, periods, dashes, and underscores. // // This member is required. Id *string @@ -92,6 +84,9 @@ func (c *Client) addOperationDeleteBucketMetricsConfigurationMiddlewares(stack * if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -119,7 +114,7 @@ func (c *Client) addOperationDeleteBucketMetricsConfigurationMiddlewares(stack * if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -131,6 +126,9 @@ func (c *Client) addOperationDeleteBucketMetricsConfigurationMiddlewares(stack * if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteBucketMetricsConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteBucketMetricsConfigurationValidationMiddleware(stack); err != nil { return err } @@ -140,6 +138,9 @@ func (c *Client) addOperationDeleteBucketMetricsConfigurationMiddlewares(stack * if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteBucketMetricsConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -155,9 +156,22 @@ func (c *Client) addOperationDeleteBucketMetricsConfigurationMiddlewares(stack * if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteBucketMetricsConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteBucketMetricsConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -192,3 +206,139 @@ func addDeleteBucketMetricsConfigurationUpdateEndpoint(stack *middleware.Stack, DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeleteBucketMetricsConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteBucketMetricsConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteBucketMetricsConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteBucketMetricsConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteBucketMetricsConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteBucketMetricsConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketOwnershipControls.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketOwnershipControls.go index 6186db5e1..ad99b6610 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketOwnershipControls.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketOwnershipControls.go @@ -4,25 +4,26 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Removes OwnershipControls for an Amazon S3 bucket. To use this operation, you // must have the s3:PutBucketOwnershipControls permission. For more information -// about Amazon S3 permissions, see Specifying Permissions in a Policy -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html). -// For information about Amazon S3 Object Ownership, see Using Object Ownership -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/about-object-ownership.html). -// The following operations are related to DeleteBucketOwnershipControls: -// -// * -// GetBucketOwnershipControls -// -// * PutBucketOwnershipControls +// about Amazon S3 permissions, see Specifying Permissions in a Policy (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html) +// . For information about Amazon S3 Object Ownership, see Using Object Ownership (https://docs.aws.amazon.com/AmazonS3/latest/dev/about-object-ownership.html) +// . The following operations are related to DeleteBucketOwnershipControls : +// - GetBucketOwnershipControls +// - PutBucketOwnershipControls func (c *Client) DeleteBucketOwnershipControls(ctx context.Context, params *DeleteBucketOwnershipControlsInput, optFns ...func(*Options)) (*DeleteBucketOwnershipControlsOutput, error) { if params == nil { params = &DeleteBucketOwnershipControlsInput{} @@ -69,6 +70,9 @@ func (c *Client) addOperationDeleteBucketOwnershipControlsMiddlewares(stack *mid if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -96,7 +100,7 @@ func (c *Client) addOperationDeleteBucketOwnershipControlsMiddlewares(stack *mid if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -108,6 +112,9 @@ func (c *Client) addOperationDeleteBucketOwnershipControlsMiddlewares(stack *mid if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteBucketOwnershipControlsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteBucketOwnershipControlsValidationMiddleware(stack); err != nil { return err } @@ -117,6 +124,9 @@ func (c *Client) addOperationDeleteBucketOwnershipControlsMiddlewares(stack *mid if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteBucketOwnershipControlsUpdateEndpoint(stack, options); err != nil { return err } @@ -132,9 +142,22 @@ func (c *Client) addOperationDeleteBucketOwnershipControlsMiddlewares(stack *mid if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteBucketOwnershipControlsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteBucketOwnershipControls(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -169,3 +192,139 @@ func addDeleteBucketOwnershipControlsUpdateEndpoint(stack *middleware.Stack, opt DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeleteBucketOwnershipControlsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteBucketOwnershipControlsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteBucketOwnershipControlsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteBucketOwnershipControlsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteBucketOwnershipControlsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteBucketOwnershipControlsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketPolicy.go index 618d9bede..1718b471a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketPolicy.go @@ -4,9 +4,15 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -19,20 +25,17 @@ import ( // have DeleteBucketPolicy permissions, Amazon S3 returns a 403 Access Denied // error. If you have the correct permissions, but you're not using an identity // that belongs to the bucket owner's account, Amazon S3 returns a 405 Method Not -// Allowed error. As a security precaution, the root user of the Amazon Web -// Services account that owns a bucket can always use this operation, even if the -// policy explicitly denies the root user the ability to perform this action. For -// more information about bucket policies, see Using Bucket Policies and -// UserPolicies -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html). The -// following operations are related to DeleteBucketPolicy -// -// * CreateBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) -// -// * -// DeleteObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) +// Allowed error. To ensure that bucket owners don't inadvertently lock themselves +// out of their own buckets, the root principal in a bucket owner's Amazon Web +// Services account can perform the GetBucketPolicy , PutBucketPolicy , and +// DeleteBucketPolicy API actions, even if their bucket policy explicitly denies +// the root principal's access. Bucket owner root principals can only be blocked +// from performing these API actions by VPC endpoint policies and Amazon Web +// Services Organizations policies. For more information about bucket policies, see +// Using Bucket Policies and UserPolicies (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) +// . The following operations are related to DeleteBucketPolicy +// - CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) +// - DeleteObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) func (c *Client) DeleteBucketPolicy(ctx context.Context, params *DeleteBucketPolicyInput, optFns ...func(*Options)) (*DeleteBucketPolicyOutput, error) { if params == nil { params = &DeleteBucketPolicyInput{} @@ -79,6 +82,9 @@ func (c *Client) addOperationDeleteBucketPolicyMiddlewares(stack *middleware.Sta if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -106,7 +112,7 @@ func (c *Client) addOperationDeleteBucketPolicyMiddlewares(stack *middleware.Sta if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -118,6 +124,9 @@ func (c *Client) addOperationDeleteBucketPolicyMiddlewares(stack *middleware.Sta if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteBucketPolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteBucketPolicyValidationMiddleware(stack); err != nil { return err } @@ -127,6 +136,9 @@ func (c *Client) addOperationDeleteBucketPolicyMiddlewares(stack *middleware.Sta if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteBucketPolicyUpdateEndpoint(stack, options); err != nil { return err } @@ -142,9 +154,22 @@ func (c *Client) addOperationDeleteBucketPolicyMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteBucketPolicyInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteBucketPolicy(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -179,3 +204,139 @@ func addDeleteBucketPolicyUpdateEndpoint(stack *middleware.Stack, options Option DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeleteBucketPolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteBucketPolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteBucketPolicyResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteBucketPolicyInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteBucketPolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteBucketPolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketReplication.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketReplication.go index ad2d772d4..441adceac 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketReplication.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketReplication.go @@ -4,9 +4,15 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -15,22 +21,14 @@ import ( // you must have permissions to perform the s3:PutReplicationConfiguration action. // The bucket owner has these permissions by default and can grant it to others. // For more information about permissions, see Permissions Related to Bucket -// Subresource Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// It can take a while for the deletion of a replication configuration to fully -// propagate. For information about replication configuration, see Replication -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication.html) in the Amazon -// S3 User Guide. The following operations are related to -// DeleteBucketReplication: -// -// * PutBucketReplication -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketReplication.html) -// -// * -// GetBucketReplication -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketReplication.html) +// Subresource Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . It can take a while for the deletion of a replication configuration to fully +// propagate. For information about replication configuration, see Replication (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication.html) +// in the Amazon S3 User Guide. The following operations are related to +// DeleteBucketReplication : +// - PutBucketReplication (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketReplication.html) +// - GetBucketReplication (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketReplication.html) func (c *Client) DeleteBucketReplication(ctx context.Context, params *DeleteBucketReplicationInput, optFns ...func(*Options)) (*DeleteBucketReplicationOutput, error) { if params == nil { params = &DeleteBucketReplicationInput{} @@ -77,6 +75,9 @@ func (c *Client) addOperationDeleteBucketReplicationMiddlewares(stack *middlewar if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -104,7 +105,7 @@ func (c *Client) addOperationDeleteBucketReplicationMiddlewares(stack *middlewar if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -116,6 +117,9 @@ func (c *Client) addOperationDeleteBucketReplicationMiddlewares(stack *middlewar if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteBucketReplicationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteBucketReplicationValidationMiddleware(stack); err != nil { return err } @@ -125,6 +129,9 @@ func (c *Client) addOperationDeleteBucketReplicationMiddlewares(stack *middlewar if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteBucketReplicationUpdateEndpoint(stack, options); err != nil { return err } @@ -140,9 +147,22 @@ func (c *Client) addOperationDeleteBucketReplicationMiddlewares(stack *middlewar if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteBucketReplicationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteBucketReplication(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -177,3 +197,139 @@ func addDeleteBucketReplicationUpdateEndpoint(stack *middleware.Stack, options O DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeleteBucketReplicationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteBucketReplicationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteBucketReplicationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteBucketReplicationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteBucketReplicationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteBucketReplicationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketTagging.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketTagging.go index 063f0bc59..1aeef1dee 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketTagging.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketTagging.go @@ -4,9 +4,15 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -14,14 +20,9 @@ import ( // Deletes the tags from the bucket. To use this operation, you must have // permission to perform the s3:PutBucketTagging action. By default, the bucket // owner has this permission and can grant this permission to others. The following -// operations are related to DeleteBucketTagging: -// -// * GetBucketTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketTagging.html) -// -// * -// PutBucketTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketTagging.html) +// operations are related to DeleteBucketTagging : +// - GetBucketTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketTagging.html) +// - PutBucketTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketTagging.html) func (c *Client) DeleteBucketTagging(ctx context.Context, params *DeleteBucketTaggingInput, optFns ...func(*Options)) (*DeleteBucketTaggingOutput, error) { if params == nil { params = &DeleteBucketTaggingInput{} @@ -68,6 +69,9 @@ func (c *Client) addOperationDeleteBucketTaggingMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -95,7 +99,7 @@ func (c *Client) addOperationDeleteBucketTaggingMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -107,6 +111,9 @@ func (c *Client) addOperationDeleteBucketTaggingMiddlewares(stack *middleware.St if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteBucketTaggingResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteBucketTaggingValidationMiddleware(stack); err != nil { return err } @@ -116,6 +123,9 @@ func (c *Client) addOperationDeleteBucketTaggingMiddlewares(stack *middleware.St if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteBucketTaggingUpdateEndpoint(stack, options); err != nil { return err } @@ -131,9 +141,22 @@ func (c *Client) addOperationDeleteBucketTaggingMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteBucketTaggingInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteBucketTagging(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -168,3 +191,139 @@ func addDeleteBucketTaggingUpdateEndpoint(stack *middleware.Stack, options Optio DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeleteBucketTaggingResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteBucketTaggingResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteBucketTaggingResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteBucketTaggingInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteBucketTaggingResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteBucketTaggingResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketWebsite.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketWebsite.go index 7eb72b86a..e7fc64b5b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketWebsite.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteBucketWebsite.go @@ -4,9 +4,15 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -21,16 +27,10 @@ import ( // bucket owners can grant other users permission to delete the website // configuration by writing a bucket policy granting them the // S3:DeleteBucketWebsite permission. For more information about hosting websites, -// see Hosting Websites on Amazon S3 -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html). The -// following operations are related to DeleteBucketWebsite: -// -// * GetBucketWebsite -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketWebsite.html) -// -// * -// PutBucketWebsite -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketWebsite.html) +// see Hosting Websites on Amazon S3 (https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html) +// . The following operations are related to DeleteBucketWebsite : +// - GetBucketWebsite (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketWebsite.html) +// - PutBucketWebsite (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketWebsite.html) func (c *Client) DeleteBucketWebsite(ctx context.Context, params *DeleteBucketWebsiteInput, optFns ...func(*Options)) (*DeleteBucketWebsiteOutput, error) { if params == nil { params = &DeleteBucketWebsiteInput{} @@ -77,6 +77,9 @@ func (c *Client) addOperationDeleteBucketWebsiteMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -104,7 +107,7 @@ func (c *Client) addOperationDeleteBucketWebsiteMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -116,6 +119,9 @@ func (c *Client) addOperationDeleteBucketWebsiteMiddlewares(stack *middleware.St if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteBucketWebsiteResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteBucketWebsiteValidationMiddleware(stack); err != nil { return err } @@ -125,6 +131,9 @@ func (c *Client) addOperationDeleteBucketWebsiteMiddlewares(stack *middleware.St if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteBucketWebsiteUpdateEndpoint(stack, options); err != nil { return err } @@ -140,9 +149,22 @@ func (c *Client) addOperationDeleteBucketWebsiteMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteBucketWebsiteInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteBucketWebsite(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -177,3 +199,139 @@ func addDeleteBucketWebsiteUpdateEndpoint(stack *middleware.Stack, options Optio DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeleteBucketWebsiteResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteBucketWebsiteResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteBucketWebsiteResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteBucketWebsiteInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteBucketWebsiteResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteBucketWebsiteResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteObject.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteObject.go index 4b4f12127..5b5cbf187 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteObject.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteObject.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -15,27 +21,22 @@ import ( // Removes the null version (if there is one) of an object and inserts a delete // marker, which becomes the latest version of the object. If there isn't a null // version, Amazon S3 does not remove any objects but will still respond that the -// command was successful. To remove a specific version, you must be the bucket -// owner and you must use the version Id subresource. Using this subresource -// permanently deletes the version. If the object deleted is a delete marker, -// Amazon S3 sets the response header, x-amz-delete-marker, to true. If the object -// you want to delete is in a bucket where the bucket versioning configuration is -// MFA Delete enabled, you must include the x-amz-mfa request header in the DELETE -// versionId request. Requests that include x-amz-mfa must use HTTPS. For more -// information about MFA Delete, see Using MFA Delete -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html). To see -// sample requests that use versioning, see Sample Request -// (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html#ExampleVersionObjectDelete). -// You can delete objects by explicitly calling DELETE Object or configure its -// lifecycle (PutBucketLifecycle -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycle.html)) -// to enable Amazon S3 to remove them for you. If you want to block users or +// command was successful. To remove a specific version, you must use the version +// Id subresource. Using this subresource permanently deletes the version. If the +// object deleted is a delete marker, Amazon S3 sets the response header, +// x-amz-delete-marker , to true. If the object you want to delete is in a bucket +// where the bucket versioning configuration is MFA Delete enabled, you must +// include the x-amz-mfa request header in the DELETE versionId request. Requests +// that include x-amz-mfa must use HTTPS. For more information about MFA Delete, +// see Using MFA Delete (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html) +// . To see sample requests that use versioning, see Sample Request (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html#ExampleVersionObjectDelete) +// . You can delete objects by explicitly calling DELETE Object or configure its +// lifecycle ( PutBucketLifecycle (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycle.html) +// ) to enable Amazon S3 to remove them for you. If you want to block users or // accounts from removing or deleting objects from your bucket, you must deny them -// the s3:DeleteObject, s3:DeleteObjectVersion, and s3:PutLifeCycleConfiguration -// actions. The following action is related to DeleteObject: -// -// * PutObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) +// the s3:DeleteObject , s3:DeleteObjectVersion , and s3:PutLifeCycleConfiguration +// actions. The following action is related to DeleteObject : +// - PutObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) func (c *Client) DeleteObject(ctx context.Context, params *DeleteObjectInput, optFns ...func(*Options)) (*DeleteObjectOutput, error) { if params == nil { params = &DeleteObjectInput{} @@ -53,23 +54,21 @@ func (c *Client) DeleteObject(ctx context.Context, params *DeleteObjectInput, op type DeleteObjectInput struct { - // The bucket name of the bucket containing the object. When using this action with - // an access point, you must direct requests to the access point hostname. The + // The bucket name of the bucket containing the object. When using this action + // with an access point, you must direct requests to the access point hostname. The // access point hostname takes the form // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -89,16 +88,18 @@ type DeleteObjectInput struct { // (access denied). ExpectedBucketOwner *string - // The concatenation of the authentication device's serial number, a space, and the - // value that is displayed on your authentication device. Required to permanently - // delete a versioned object if versioning is configured with MFA delete enabled. + // The concatenation of the authentication device's serial number, a space, and + // the value that is displayed on your authentication device. Required to + // permanently delete a versioned object if versioning is configured with MFA + // delete enabled. MFA *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -110,8 +111,10 @@ type DeleteObjectInput struct { type DeleteObjectOutput struct { - // Specifies whether the versioned object that was permanently deleted was (true) - // or was not (false) a delete marker. + // Indicates whether the specified object version that was permanently deleted was + // (true) or was not (false) a delete marker before deletion. In a simple DELETE, + // this header indicates whether (true) or not (false) the current version of the + // object is a delete marker. DeleteMarker bool // If present, indicates that the requester was successfully charged for the @@ -137,6 +140,9 @@ func (c *Client) addOperationDeleteObjectMiddlewares(stack *middleware.Stack, op if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -164,7 +170,7 @@ func (c *Client) addOperationDeleteObjectMiddlewares(stack *middleware.Stack, op if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -176,6 +182,9 @@ func (c *Client) addOperationDeleteObjectMiddlewares(stack *middleware.Stack, op if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteObjectResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteObjectValidationMiddleware(stack); err != nil { return err } @@ -185,6 +194,9 @@ func (c *Client) addOperationDeleteObjectMiddlewares(stack *middleware.Stack, op if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteObjectUpdateEndpoint(stack, options); err != nil { return err } @@ -200,9 +212,22 @@ func (c *Client) addOperationDeleteObjectMiddlewares(stack *middleware.Stack, op if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteObjectInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteObject(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -268,3 +293,139 @@ func addDeleteObjectPayloadAsUnsigned(stack *middleware.Stack, options Options) v4.RemoveComputePayloadSHA256Middleware(stack) return v4.AddUnsignedPayloadMiddleware(stack) } + +type opDeleteObjectResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteObjectResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteObjectResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteObjectInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteObjectResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteObjectResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteObjectTagging.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteObjectTagging.go index 0d1bb7399..41d46e48f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteObjectTagging.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteObjectTagging.go @@ -4,28 +4,28 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Removes the entire tag set from the specified object. For more information about -// managing object tags, see Object Tagging -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html). To use -// this operation, you must have permission to perform the s3:DeleteObjectTagging -// action. To delete tags of a specific object version, add the versionId query -// parameter in the request. You will need permission for the +// Removes the entire tag set from the specified object. For more information +// about managing object tags, see Object Tagging (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html) +// . To use this operation, you must have permission to perform the +// s3:DeleteObjectTagging action. To delete tags of a specific object version, add +// the versionId query parameter in the request. You will need permission for the // s3:DeleteObjectVersionTagging action. The following operations are related to -// DeleteBucketMetricsConfiguration: -// -// * PutObjectTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html) -// -// * -// GetObjectTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html) +// DeleteObjectTagging : +// - PutObjectTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html) +// - GetObjectTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html) func (c *Client) DeleteObjectTagging(ctx context.Context, params *DeleteObjectTaggingInput, optFns ...func(*Options)) (*DeleteObjectTaggingOutput, error) { if params == nil { params = &DeleteObjectTaggingInput{} @@ -43,23 +43,21 @@ func (c *Client) DeleteObjectTagging(ctx context.Context, params *DeleteObjectTa type DeleteObjectTaggingInput struct { - // The bucket name containing the objects from which to remove the tags. When using - // this action with an access point, you must direct requests to the access point - // hostname. The access point hostname takes the form + // The bucket name containing the objects from which to remove the tags. When + // using this action with an access point, you must direct requests to the access + // point hostname. The access point hostname takes the form // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -100,6 +98,9 @@ func (c *Client) addOperationDeleteObjectTaggingMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -127,7 +128,7 @@ func (c *Client) addOperationDeleteObjectTaggingMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -139,6 +140,9 @@ func (c *Client) addOperationDeleteObjectTaggingMiddlewares(stack *middleware.St if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteObjectTaggingResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteObjectTaggingValidationMiddleware(stack); err != nil { return err } @@ -148,6 +152,9 @@ func (c *Client) addOperationDeleteObjectTaggingMiddlewares(stack *middleware.St if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteObjectTaggingUpdateEndpoint(stack, options); err != nil { return err } @@ -163,9 +170,22 @@ func (c *Client) addOperationDeleteObjectTaggingMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteObjectTaggingInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteObjectTagging(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -200,3 +220,139 @@ func addDeleteObjectTaggingUpdateEndpoint(stack *middleware.Stack, options Optio DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeleteObjectTaggingResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteObjectTaggingResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteObjectTaggingResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteObjectTaggingInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteObjectTaggingResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteObjectTaggingResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteObjects.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteObjects.go index 50078da53..b494c18ae 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteObjects.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeleteObjects.go @@ -4,11 +4,17 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -33,31 +39,16 @@ import ( // even if there are non-versioned objects you are trying to delete. If you provide // an invalid token, whether there are versioned keys in the request or not, the // entire Multi-Object Delete request will fail. For information about MFA Delete, -// see MFA Delete -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html#MultiFactorAuthenticationDelete). -// Finally, the Content-MD5 header is required for all Multi-Object Delete +// see MFA Delete (https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html#MultiFactorAuthenticationDelete) +// . Finally, the Content-MD5 header is required for all Multi-Object Delete // requests. Amazon S3 uses the header value to ensure that your request body has // not been altered in transit. The following operations are related to -// DeleteObjects: -// -// * CreateMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) -// -// * -// UploadPart -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) -// -// * -// CompleteMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) -// -// * -// ListParts -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) -// -// * -// AbortMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) +// DeleteObjects : +// - CreateMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) +// - UploadPart (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) +// - CompleteMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) +// - ListParts (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) +// - AbortMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) func (c *Client) DeleteObjects(ctx context.Context, params *DeleteObjectsInput, optFns ...func(*Options)) (*DeleteObjectsOutput, error) { if params == nil { params = &DeleteObjectsInput{} @@ -75,23 +66,21 @@ func (c *Client) DeleteObjects(ctx context.Context, params *DeleteObjectsInput, type DeleteObjectsInput struct { - // The bucket name containing the objects to delete. When using this action with an - // access point, you must direct requests to the access point hostname. The access - // point hostname takes the form + // The bucket name containing the objects to delete. When using this action with + // an access point, you must direct requests to the access point hostname. The + // access point hostname takes the form // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -110,9 +99,8 @@ type DeleteObjectsInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. This checksum algorithm must // be the same for all parts and it match the checksum value supplied in the @@ -124,16 +112,18 @@ type DeleteObjectsInput struct { // (access denied). ExpectedBucketOwner *string - // The concatenation of the authentication device's serial number, a space, and the - // value that is displayed on your authentication device. Required to permanently - // delete a versioned object if versioning is configured with MFA delete enabled. + // The concatenation of the authentication device's serial number, a space, and + // the value that is displayed on your authentication device. Required to + // permanently delete a versioned object if versioning is configured with MFA + // delete enabled. MFA *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -169,6 +159,9 @@ func (c *Client) addOperationDeleteObjectsMiddlewares(stack *middleware.Stack, o if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -196,7 +189,7 @@ func (c *Client) addOperationDeleteObjectsMiddlewares(stack *middleware.Stack, o if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -208,6 +201,9 @@ func (c *Client) addOperationDeleteObjectsMiddlewares(stack *middleware.Stack, o if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeleteObjectsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeleteObjectsValidationMiddleware(stack); err != nil { return err } @@ -217,6 +213,9 @@ func (c *Client) addOperationDeleteObjectsMiddlewares(stack *middleware.Stack, o if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeleteObjectsInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -235,9 +234,22 @@ func (c *Client) addOperationDeleteObjectsMiddlewares(stack *middleware.Stack, o if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeleteObjectsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeleteObjects(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -247,8 +259,8 @@ func newServiceMetadataMiddleware_opDeleteObjects(region string) *awsmiddleware. } } -// getDeleteObjectsRequestAlgorithmMember gets the request checksum algorithm value -// provided as input. +// getDeleteObjectsRequestAlgorithmMember gets the request checksum algorithm +// value provided as input. func getDeleteObjectsRequestAlgorithmMember(input interface{}) (string, bool) { in := input.(*DeleteObjectsInput) if len(in.ChecksumAlgorithm) == 0 { @@ -292,3 +304,139 @@ func addDeleteObjectsUpdateEndpoint(stack *middleware.Stack, options Options) er DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeleteObjectsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeleteObjectsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeleteObjectsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeleteObjectsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeleteObjectsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeleteObjectsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeletePublicAccessBlock.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeletePublicAccessBlock.go index 3defd538c..2bdbe4217 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeletePublicAccessBlock.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_DeletePublicAccessBlock.go @@ -4,37 +4,29 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Removes the PublicAccessBlock configuration for an Amazon S3 bucket. To use this -// operation, you must have the s3:PutBucketPublicAccessBlock permission. For more -// information about permissions, see Permissions Related to Bucket Subresource -// Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// The following operations are related to DeletePublicAccessBlock: -// -// * Using Amazon -// S3 Block Public Access -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html) -// -// * -// GetPublicAccessBlock -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetPublicAccessBlock.html) -// -// * -// PutPublicAccessBlock -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutPublicAccessBlock.html) -// -// * -// GetBucketPolicyStatus -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketPolicyStatus.html) +// Removes the PublicAccessBlock configuration for an Amazon S3 bucket. To use +// this operation, you must have the s3:PutBucketPublicAccessBlock permission. For +// more information about permissions, see Permissions Related to Bucket +// Subresource Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . The following operations are related to DeletePublicAccessBlock : +// - Using Amazon S3 Block Public Access (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html) +// - GetPublicAccessBlock (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetPublicAccessBlock.html) +// - PutPublicAccessBlock (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutPublicAccessBlock.html) +// - GetBucketPolicyStatus (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketPolicyStatus.html) func (c *Client) DeletePublicAccessBlock(ctx context.Context, params *DeletePublicAccessBlockInput, optFns ...func(*Options)) (*DeletePublicAccessBlockOutput, error) { if params == nil { params = &DeletePublicAccessBlockInput{} @@ -81,6 +73,9 @@ func (c *Client) addOperationDeletePublicAccessBlockMiddlewares(stack *middlewar if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -108,7 +103,7 @@ func (c *Client) addOperationDeletePublicAccessBlockMiddlewares(stack *middlewar if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -120,6 +115,9 @@ func (c *Client) addOperationDeletePublicAccessBlockMiddlewares(stack *middlewar if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addDeletePublicAccessBlockResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDeletePublicAccessBlockValidationMiddleware(stack); err != nil { return err } @@ -129,6 +127,9 @@ func (c *Client) addOperationDeletePublicAccessBlockMiddlewares(stack *middlewar if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addDeletePublicAccessBlockUpdateEndpoint(stack, options); err != nil { return err } @@ -144,9 +145,22 @@ func (c *Client) addOperationDeletePublicAccessBlockMiddlewares(stack *middlewar if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *DeletePublicAccessBlockInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opDeletePublicAccessBlock(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -181,3 +195,139 @@ func addDeletePublicAccessBlockUpdateEndpoint(stack *middleware.Stack, options O DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opDeletePublicAccessBlockResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDeletePublicAccessBlockResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDeletePublicAccessBlockResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*DeletePublicAccessBlockInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDeletePublicAccessBlockResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDeletePublicAccessBlockResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketAccelerateConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketAccelerateConfiguration.go index d1690f3ea..f11b25aa3 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketAccelerateConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketAccelerateConfiguration.go @@ -4,38 +4,39 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // This implementation of the GET action uses the accelerate subresource to return // the Transfer Acceleration state of a bucket, which is either Enabled or -// Suspended. Amazon S3 Transfer Acceleration is a bucket-level feature that +// Suspended . Amazon S3 Transfer Acceleration is a bucket-level feature that // enables you to perform faster data transfers to and from Amazon S3. To use this // operation, you must have permission to perform the s3:GetAccelerateConfiguration // action. The bucket owner has this permission by default. The bucket owner can // grant this permission to others. For more information about permissions, see -// Permissions Related to Bucket Subresource Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// Permissions Related to Bucket Subresource Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) // in the Amazon S3 User Guide. You set the Transfer Acceleration state of an // existing bucket to Enabled or Suspended by using the -// PutBucketAccelerateConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAccelerateConfiguration.html) +// PutBucketAccelerateConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAccelerateConfiguration.html) // operation. A GET accelerate request does not return a state value for a bucket // that has no transfer acceleration state. A bucket has no Transfer Acceleration // state if a state has never been set on the bucket. For more information about -// transfer acceleration, see Transfer Acceleration -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html) in -// the Amazon S3 User Guide. Related Resources -// -// * PutBucketAccelerateConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAccelerateConfiguration.html) +// transfer acceleration, see Transfer Acceleration (https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html) +// in the Amazon S3 User Guide. The following operations are related to +// GetBucketAccelerateConfiguration : +// - PutBucketAccelerateConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAccelerateConfiguration.html) func (c *Client) GetBucketAccelerateConfiguration(ctx context.Context, params *GetBucketAccelerateConfigurationInput, optFns ...func(*Options)) (*GetBucketAccelerateConfigurationOutput, error) { if params == nil { params = &GetBucketAccelerateConfigurationInput{} @@ -63,11 +64,24 @@ type GetBucketAccelerateConfigurationInput struct { // (access denied). ExpectedBucketOwner *string + // Confirms that the requester knows that they will be charged for the request. + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // in the Amazon S3 User Guide. + RequestPayer types.RequestPayer + noSmithyDocumentSerde } type GetBucketAccelerateConfigurationOutput struct { + // If present, indicates that the requester was successfully charged for the + // request. + RequestCharged types.RequestCharged + // The accelerate configuration of the bucket. Status types.BucketAccelerateStatus @@ -86,6 +100,9 @@ func (c *Client) addOperationGetBucketAccelerateConfigurationMiddlewares(stack * if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -113,7 +130,7 @@ func (c *Client) addOperationGetBucketAccelerateConfigurationMiddlewares(stack * if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -125,6 +142,9 @@ func (c *Client) addOperationGetBucketAccelerateConfigurationMiddlewares(stack * if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketAccelerateConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketAccelerateConfigurationValidationMiddleware(stack); err != nil { return err } @@ -134,6 +154,9 @@ func (c *Client) addOperationGetBucketAccelerateConfigurationMiddlewares(stack * if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketAccelerateConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -149,9 +172,22 @@ func (c *Client) addOperationGetBucketAccelerateConfigurationMiddlewares(stack * if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketAccelerateConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketAccelerateConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -186,3 +222,139 @@ func addGetBucketAccelerateConfigurationUpdateEndpoint(stack *middleware.Stack, DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketAccelerateConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketAccelerateConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketAccelerateConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketAccelerateConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketAccelerateConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketAccelerateConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketAcl.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketAcl.go index 610762883..623349519 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketAcl.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketAcl.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -16,16 +22,21 @@ import ( // access control list (ACL) of a bucket. To use GET to return the ACL of the // bucket, you must have READ_ACP access to the bucket. If READ_ACP permission is // granted to the anonymous user, you can return the ACL of the bucket without -// using an authorization header. If your bucket uses the bucket owner enforced -// setting for S3 Object Ownership, requests to read ACLs are still supported and -// return the bucket-owner-full-control ACL with the owner being the account that -// created the bucket. For more information, see Controlling object ownership and -// disabling ACLs -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) -// in the Amazon S3 User Guide. Related Resources -// -// * ListObjects -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html) +// using an authorization header. To use this API operation against an access +// point, provide the alias of the access point in place of the bucket name. To use +// this API operation against an Object Lambda access point, provide the alias of +// the Object Lambda access point in place of the bucket name. If the Object Lambda +// access point alias in a request is not valid, the error code +// InvalidAccessPointAliasError is returned. For more information about +// InvalidAccessPointAliasError , see List of Error Codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) +// . If your bucket uses the bucket owner enforced setting for S3 Object Ownership, +// requests to read ACLs are still supported and return the +// bucket-owner-full-control ACL with the owner being the account that created the +// bucket. For more information, see Controlling object ownership and disabling +// ACLs (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) +// in the Amazon S3 User Guide. The following operations are related to +// GetBucketAcl : +// - ListObjects (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html) func (c *Client) GetBucketAcl(ctx context.Context, params *GetBucketAclInput, optFns ...func(*Options)) (*GetBucketAclOutput, error) { if params == nil { params = &GetBucketAclInput{} @@ -43,7 +54,14 @@ func (c *Client) GetBucketAcl(ctx context.Context, params *GetBucketAclInput, op type GetBucketAclInput struct { - // Specifies the S3 bucket whose ACL is being requested. + // Specifies the S3 bucket whose ACL is being requested. To use this API operation + // against an access point, provide the alias of the access point in place of the + // bucket name. To use this API operation against an Object Lambda access point, + // provide the alias of the Object Lambda access point in place of the bucket name. + // If the Object Lambda access point alias in a request is not valid, the error + // code InvalidAccessPointAliasError is returned. For more information about + // InvalidAccessPointAliasError , see List of Error Codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) + // . // // This member is required. Bucket *string @@ -79,6 +97,9 @@ func (c *Client) addOperationGetBucketAclMiddlewares(stack *middleware.Stack, op if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -106,7 +127,7 @@ func (c *Client) addOperationGetBucketAclMiddlewares(stack *middleware.Stack, op if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -118,6 +139,9 @@ func (c *Client) addOperationGetBucketAclMiddlewares(stack *middleware.Stack, op if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketAclResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketAclValidationMiddleware(stack); err != nil { return err } @@ -127,6 +151,9 @@ func (c *Client) addOperationGetBucketAclMiddlewares(stack *middleware.Stack, op if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketAclUpdateEndpoint(stack, options); err != nil { return err } @@ -142,9 +169,22 @@ func (c *Client) addOperationGetBucketAclMiddlewares(stack *middleware.Stack, op if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketAclInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketAcl(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -179,3 +219,139 @@ func addGetBucketAclUpdateEndpoint(stack *middleware.Stack, options Options) err DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketAclResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketAclResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketAclResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketAclInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketAclResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketAclResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketAnalyticsConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketAnalyticsConfiguration.go index bf2c3be67..bc8b5c31d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketAnalyticsConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketAnalyticsConfiguration.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -17,26 +23,15 @@ import ( // operation, you must have permissions to perform the s3:GetAnalyticsConfiguration // action. The bucket owner has this permission by default. The bucket owner can // grant this permission to others. For more information about permissions, see -// Permissions Related to Bucket Subresource Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// Permissions Related to Bucket Subresource Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) // in the Amazon S3 User Guide. For information about Amazon S3 analytics feature, -// see Amazon S3 Analytics – Storage Class Analysis -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/analytics-storage-class.html) -// in the Amazon S3 User Guide. Related Resources -// -// * -// DeleteBucketAnalyticsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketAnalyticsConfiguration.html) -// -// * -// ListBucketAnalyticsConfigurations -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketAnalyticsConfigurations.html) -// -// * -// PutBucketAnalyticsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAnalyticsConfiguration.html) +// see Amazon S3 Analytics – Storage Class Analysis (https://docs.aws.amazon.com/AmazonS3/latest/dev/analytics-storage-class.html) +// in the Amazon S3 User Guide. The following operations are related to +// GetBucketAnalyticsConfiguration : +// - DeleteBucketAnalyticsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketAnalyticsConfiguration.html) +// - ListBucketAnalyticsConfigurations (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketAnalyticsConfigurations.html) +// - PutBucketAnalyticsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAnalyticsConfiguration.html) func (c *Client) GetBucketAnalyticsConfiguration(ctx context.Context, params *GetBucketAnalyticsConfigurationInput, optFns ...func(*Options)) (*GetBucketAnalyticsConfigurationOutput, error) { if params == nil { params = &GetBucketAnalyticsConfigurationInput{} @@ -92,6 +87,9 @@ func (c *Client) addOperationGetBucketAnalyticsConfigurationMiddlewares(stack *m if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -119,7 +117,7 @@ func (c *Client) addOperationGetBucketAnalyticsConfigurationMiddlewares(stack *m if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -131,6 +129,9 @@ func (c *Client) addOperationGetBucketAnalyticsConfigurationMiddlewares(stack *m if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketAnalyticsConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketAnalyticsConfigurationValidationMiddleware(stack); err != nil { return err } @@ -140,6 +141,9 @@ func (c *Client) addOperationGetBucketAnalyticsConfigurationMiddlewares(stack *m if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketAnalyticsConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -155,9 +159,22 @@ func (c *Client) addOperationGetBucketAnalyticsConfigurationMiddlewares(stack *m if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketAnalyticsConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketAnalyticsConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -192,3 +209,139 @@ func addGetBucketAnalyticsConfigurationUpdateEndpoint(stack *middleware.Stack, o DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketAnalyticsConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketAnalyticsConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketAnalyticsConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketAnalyticsConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketAnalyticsConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketAnalyticsConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketCors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketCors.go index 0ed61273a..09437e26a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketCors.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketCors.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -15,17 +21,17 @@ import ( // Returns the Cross-Origin Resource Sharing (CORS) configuration information set // for the bucket. To use this operation, you must have permission to perform the // s3:GetBucketCORS action. By default, the bucket owner has this permission and -// can grant it to others. For more information about CORS, see Enabling -// Cross-Origin Resource Sharing -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html). The following -// operations are related to GetBucketCors: -// -// * PutBucketCors -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html) -// -// * -// DeleteBucketCors -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html) +// can grant it to others. To use this API operation against an access point, +// provide the alias of the access point in place of the bucket name. To use this +// API operation against an Object Lambda access point, provide the alias of the +// Object Lambda access point in place of the bucket name. If the Object Lambda +// access point alias in a request is not valid, the error code +// InvalidAccessPointAliasError is returned. For more information about +// InvalidAccessPointAliasError , see List of Error Codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) +// . For more information about CORS, see Enabling Cross-Origin Resource Sharing (https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html) +// . The following operations are related to GetBucketCors : +// - PutBucketCors (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html) +// - DeleteBucketCors (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html) func (c *Client) GetBucketCors(ctx context.Context, params *GetBucketCorsInput, optFns ...func(*Options)) (*GetBucketCorsOutput, error) { if params == nil { params = &GetBucketCorsInput{} @@ -43,7 +49,14 @@ func (c *Client) GetBucketCors(ctx context.Context, params *GetBucketCorsInput, type GetBucketCorsInput struct { - // The bucket name for which to get the cors configuration. + // The bucket name for which to get the cors configuration. To use this API + // operation against an access point, provide the alias of the access point in + // place of the bucket name. To use this API operation against an Object Lambda + // access point, provide the alias of the Object Lambda access point in place of + // the bucket name. If the Object Lambda access point alias in a request is not + // valid, the error code InvalidAccessPointAliasError is returned. For more + // information about InvalidAccessPointAliasError , see List of Error Codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) + // . // // This member is required. Bucket *string @@ -77,6 +90,9 @@ func (c *Client) addOperationGetBucketCorsMiddlewares(stack *middleware.Stack, o if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -104,7 +120,7 @@ func (c *Client) addOperationGetBucketCorsMiddlewares(stack *middleware.Stack, o if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -116,6 +132,9 @@ func (c *Client) addOperationGetBucketCorsMiddlewares(stack *middleware.Stack, o if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketCorsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketCorsValidationMiddleware(stack); err != nil { return err } @@ -125,6 +144,9 @@ func (c *Client) addOperationGetBucketCorsMiddlewares(stack *middleware.Stack, o if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketCorsUpdateEndpoint(stack, options); err != nil { return err } @@ -140,9 +162,22 @@ func (c *Client) addOperationGetBucketCorsMiddlewares(stack *middleware.Stack, o if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketCorsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketCors(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -177,3 +212,139 @@ func addGetBucketCorsUpdateEndpoint(stack *middleware.Stack, options Options) er DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketCorsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketCorsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketCorsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketCorsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketCorsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketCorsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketEncryption.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketEncryption.go index 7fa92fc5f..b60c5f46a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketEncryption.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketEncryption.go @@ -4,37 +4,34 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Returns the default encryption configuration for an Amazon S3 bucket. If the -// bucket does not have a default encryption configuration, GetBucketEncryption -// returns ServerSideEncryptionConfigurationNotFoundError. For information about -// the Amazon S3 default encryption feature, see Amazon S3 Default Bucket -// Encryption -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html). To use -// this operation, you must have permission to perform the -// s3:GetEncryptionConfiguration action. The bucket owner has this permission by -// default. The bucket owner can grant this permission to others. For more -// information about permissions, see Permissions Related to Bucket Subresource -// Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// The following operations are related to GetBucketEncryption: -// -// * -// PutBucketEncryption -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) -// -// * -// DeleteBucketEncryption -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketEncryption.html) +// Returns the default encryption configuration for an Amazon S3 bucket. By +// default, all buckets have a default encryption configuration that uses +// server-side encryption with Amazon S3 managed keys (SSE-S3). For information +// about the bucket default encryption feature, see Amazon S3 Bucket Default +// Encryption (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html) +// in the Amazon S3 User Guide. To use this operation, you must have permission to +// perform the s3:GetEncryptionConfiguration action. The bucket owner has this +// permission by default. The bucket owner can grant this permission to others. For +// more information about permissions, see Permissions Related to Bucket +// Subresource Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . The following operations are related to GetBucketEncryption : +// - PutBucketEncryption (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html) +// - DeleteBucketEncryption (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketEncryption.html) func (c *Client) GetBucketEncryption(ctx context.Context, params *GetBucketEncryptionInput, optFns ...func(*Options)) (*GetBucketEncryptionOutput, error) { if params == nil { params = &GetBucketEncryptionInput{} @@ -86,6 +83,9 @@ func (c *Client) addOperationGetBucketEncryptionMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -113,7 +113,7 @@ func (c *Client) addOperationGetBucketEncryptionMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -125,6 +125,9 @@ func (c *Client) addOperationGetBucketEncryptionMiddlewares(stack *middleware.St if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketEncryptionResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketEncryptionValidationMiddleware(stack); err != nil { return err } @@ -134,6 +137,9 @@ func (c *Client) addOperationGetBucketEncryptionMiddlewares(stack *middleware.St if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketEncryptionUpdateEndpoint(stack, options); err != nil { return err } @@ -149,9 +155,22 @@ func (c *Client) addOperationGetBucketEncryptionMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketEncryptionInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketEncryption(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -186,3 +205,139 @@ func addGetBucketEncryptionUpdateEndpoint(stack *middleware.Stack, options Optio DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketEncryptionResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketEncryptionResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketEncryptionResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketEncryptionInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketEncryptionResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketEncryptionResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketIntelligentTieringConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketIntelligentTieringConfiguration.go index 70bbb9dfb..259b265bd 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketIntelligentTieringConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketIntelligentTieringConfiguration.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -25,21 +31,11 @@ import ( // monitored and not eligible for auto-tiering. Smaller objects can be stored, but // they are always charged at the Frequent Access tier rates in the S3 // Intelligent-Tiering storage class. For more information, see Storage class for -// automatically optimizing frequently and infrequently accessed objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access). -// Operations related to GetBucketIntelligentTieringConfiguration include: -// -// * -// DeleteBucketIntelligentTieringConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketIntelligentTieringConfiguration.html) -// -// * -// PutBucketIntelligentTieringConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketIntelligentTieringConfiguration.html) -// -// * -// ListBucketIntelligentTieringConfigurations -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketIntelligentTieringConfigurations.html) +// automatically optimizing frequently and infrequently accessed objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access) +// . Operations related to GetBucketIntelligentTieringConfiguration include: +// - DeleteBucketIntelligentTieringConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketIntelligentTieringConfiguration.html) +// - PutBucketIntelligentTieringConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketIntelligentTieringConfiguration.html) +// - ListBucketIntelligentTieringConfigurations (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketIntelligentTieringConfigurations.html) func (c *Client) GetBucketIntelligentTieringConfiguration(ctx context.Context, params *GetBucketIntelligentTieringConfigurationInput, optFns ...func(*Options)) (*GetBucketIntelligentTieringConfigurationOutput, error) { if params == nil { params = &GetBucketIntelligentTieringConfigurationInput{} @@ -91,6 +87,9 @@ func (c *Client) addOperationGetBucketIntelligentTieringConfigurationMiddlewares if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -118,7 +117,7 @@ func (c *Client) addOperationGetBucketIntelligentTieringConfigurationMiddlewares if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -130,6 +129,9 @@ func (c *Client) addOperationGetBucketIntelligentTieringConfigurationMiddlewares if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketIntelligentTieringConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketIntelligentTieringConfigurationValidationMiddleware(stack); err != nil { return err } @@ -139,6 +141,9 @@ func (c *Client) addOperationGetBucketIntelligentTieringConfigurationMiddlewares if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketIntelligentTieringConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -154,9 +159,22 @@ func (c *Client) addOperationGetBucketIntelligentTieringConfigurationMiddlewares if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketIntelligentTieringConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketIntelligentTieringConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -191,3 +209,139 @@ func addGetBucketIntelligentTieringConfigurationUpdateEndpoint(stack *middleware DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketIntelligentTieringConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketIntelligentTieringConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketIntelligentTieringConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketIntelligentTieringConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketIntelligentTieringConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketIntelligentTieringConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketInventoryConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketInventoryConfiguration.go index f35a4606c..4863f979c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketInventoryConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketInventoryConfiguration.go @@ -4,37 +4,31 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns an inventory configuration (identified by the inventory configuration // ID) from the bucket. To use this operation, you must have permissions to perform -// the s3:GetInventoryConfiguration action. The bucket owner has this permission by -// default and can grant this permission to others. For more information about -// permissions, see Permissions Related to Bucket Subresource Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// For information about the Amazon S3 inventory feature, see Amazon S3 Inventory -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html). The -// following operations are related to GetBucketInventoryConfiguration: -// -// * -// DeleteBucketInventoryConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketInventoryConfiguration.html) -// -// * -// ListBucketInventoryConfigurations -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketInventoryConfigurations.html) -// -// * -// PutBucketInventoryConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketInventoryConfiguration.html) +// the s3:GetInventoryConfiguration action. The bucket owner has this permission +// by default and can grant this permission to others. For more information about +// permissions, see Permissions Related to Bucket Subresource Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . For information about the Amazon S3 inventory feature, see Amazon S3 Inventory (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html) +// . The following operations are related to GetBucketInventoryConfiguration : +// - DeleteBucketInventoryConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketInventoryConfiguration.html) +// - ListBucketInventoryConfigurations (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketInventoryConfigurations.html) +// - PutBucketInventoryConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketInventoryConfiguration.html) func (c *Client) GetBucketInventoryConfiguration(ctx context.Context, params *GetBucketInventoryConfigurationInput, optFns ...func(*Options)) (*GetBucketInventoryConfigurationOutput, error) { if params == nil { params = &GetBucketInventoryConfigurationInput{} @@ -90,6 +84,9 @@ func (c *Client) addOperationGetBucketInventoryConfigurationMiddlewares(stack *m if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -117,7 +114,7 @@ func (c *Client) addOperationGetBucketInventoryConfigurationMiddlewares(stack *m if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -129,6 +126,9 @@ func (c *Client) addOperationGetBucketInventoryConfigurationMiddlewares(stack *m if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketInventoryConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketInventoryConfigurationValidationMiddleware(stack); err != nil { return err } @@ -138,6 +138,9 @@ func (c *Client) addOperationGetBucketInventoryConfigurationMiddlewares(stack *m if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketInventoryConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -153,9 +156,22 @@ func (c *Client) addOperationGetBucketInventoryConfigurationMiddlewares(stack *m if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketInventoryConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketInventoryConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -190,3 +206,139 @@ func addGetBucketInventoryConfigurationUpdateEndpoint(stack *middleware.Stack, o DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketInventoryConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketInventoryConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketInventoryConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketInventoryConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketInventoryConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketInventoryConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketLifecycleConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketLifecycleConfiguration.go index 5d72d2ebc..da3e47d4b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketLifecycleConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketLifecycleConfiguration.go @@ -4,59 +4,45 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Bucket lifecycle configuration now supports specifying a lifecycle rule using an -// object key name prefix, one or more object tags, or a combination of both. +// Bucket lifecycle configuration now supports specifying a lifecycle rule using +// an object key name prefix, one or more object tags, or a combination of both. // Accordingly, this section describes the latest API. The response describes the // new filter element that you can use to specify a filter to select a subset of // objects to which the rule applies. If you are using a previous version of the // lifecycle configuration, it still works. For the earlier action, see -// GetBucketLifecycle -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycle.html). -// Returns the lifecycle configuration information set on the bucket. For -// information about lifecycle configuration, see Object Lifecycle Management -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html). To -// use this operation, you must have permission to perform the +// GetBucketLifecycle (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycle.html) +// . Returns the lifecycle configuration information set on the bucket. For +// information about lifecycle configuration, see Object Lifecycle Management (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html) +// . To use this operation, you must have permission to perform the // s3:GetLifecycleConfiguration action. The bucket owner has this permission, by // default. The bucket owner can grant this permission to others. For more // information about permissions, see Permissions Related to Bucket Subresource -// Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// GetBucketLifecycleConfiguration has the following special error: +// Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . GetBucketLifecycleConfiguration has the following special error: +// - Error code: NoSuchLifecycleConfiguration +// - Description: The lifecycle configuration does not exist. +// - HTTP Status Code: 404 Not Found +// - SOAP Fault Code Prefix: Client // -// * Error code: -// NoSuchLifecycleConfiguration -// -// * Description: The lifecycle configuration does -// not exist. -// -// * HTTP Status Code: 404 Not Found -// -// * SOAP Fault Code Prefix: -// Client -// -// The following operations are related to -// GetBucketLifecycleConfiguration: -// -// * GetBucketLifecycle -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycle.html) -// -// * -// PutBucketLifecycle -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycle.html) -// -// * -// DeleteBucketLifecycle -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketLifecycle.html) +// The following operations are related to GetBucketLifecycleConfiguration : +// - GetBucketLifecycle (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycle.html) +// - PutBucketLifecycle (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycle.html) +// - DeleteBucketLifecycle (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketLifecycle.html) func (c *Client) GetBucketLifecycleConfiguration(ctx context.Context, params *GetBucketLifecycleConfigurationInput, optFns ...func(*Options)) (*GetBucketLifecycleConfigurationOutput, error) { if params == nil { params = &GetBucketLifecycleConfigurationInput{} @@ -107,6 +93,9 @@ func (c *Client) addOperationGetBucketLifecycleConfigurationMiddlewares(stack *m if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -134,7 +123,7 @@ func (c *Client) addOperationGetBucketLifecycleConfigurationMiddlewares(stack *m if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -146,6 +135,9 @@ func (c *Client) addOperationGetBucketLifecycleConfigurationMiddlewares(stack *m if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketLifecycleConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketLifecycleConfigurationValidationMiddleware(stack); err != nil { return err } @@ -155,6 +147,9 @@ func (c *Client) addOperationGetBucketLifecycleConfigurationMiddlewares(stack *m if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketLifecycleConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -170,9 +165,22 @@ func (c *Client) addOperationGetBucketLifecycleConfigurationMiddlewares(stack *m if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketLifecycleConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketLifecycleConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -207,3 +215,139 @@ func addGetBucketLifecycleConfigurationUpdateEndpoint(stack *middleware.Stack, o DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketLifecycleConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketLifecycleConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketLifecycleConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketLifecycleConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketLifecycleConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketLifecycleConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketLocation.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketLocation.go index fb8ff30fd..9404b4576 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketLocation.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketLocation.go @@ -6,13 +6,18 @@ import ( "bytes" "context" "encoding/xml" + "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" smithy "github.com/aws/smithy-go" smithyxml "github.com/aws/smithy-go/encoding/xml" + smithyendpoints "github.com/aws/smithy-go/endpoints" smithyio "github.com/aws/smithy-go/io" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -21,19 +26,20 @@ import ( // Returns the Region the bucket resides in. You set the bucket's Region using the // LocationConstraint request parameter in a CreateBucket request. For more -// information, see CreateBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html). To use -// this implementation of the operation, you must be the bucket owner. To use this -// API against an access point, provide the alias of the access point in place of -// the bucket name. The following operations are related to GetBucketLocation: -// -// * -// GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) -// -// * -// CreateBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) +// information, see CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) +// . To use this API operation against an access point, provide the alias of the +// access point in place of the bucket name. To use this API operation against an +// Object Lambda access point, provide the alias of the Object Lambda access point +// in place of the bucket name. If the Object Lambda access point alias in a +// request is not valid, the error code InvalidAccessPointAliasError is returned. +// For more information about InvalidAccessPointAliasError , see List of Error +// Codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) +// . We recommend that you use HeadBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html) +// to return the Region that a bucket resides in. For backward compatibility, +// Amazon S3 continues to support GetBucketLocation. The following operations are +// related to GetBucketLocation : +// - GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// - CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) func (c *Client) GetBucketLocation(ctx context.Context, params *GetBucketLocationInput, optFns ...func(*Options)) (*GetBucketLocationOutput, error) { if params == nil { params = &GetBucketLocationInput{} @@ -51,7 +57,14 @@ func (c *Client) GetBucketLocation(ctx context.Context, params *GetBucketLocatio type GetBucketLocationInput struct { - // The name of the bucket for which to get the location. + // The name of the bucket for which to get the location. To use this API operation + // against an access point, provide the alias of the access point in place of the + // bucket name. To use this API operation against an Object Lambda access point, + // provide the alias of the Object Lambda access point in place of the bucket name. + // If the Object Lambda access point alias in a request is not valid, the error + // code InvalidAccessPointAliasError is returned. For more information about + // InvalidAccessPointAliasError , see List of Error Codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) + // . // // This member is required. Bucket *string @@ -67,9 +80,8 @@ type GetBucketLocationInput struct { type GetBucketLocationOutput struct { // Specifies the Region where the bucket resides. For a list of all the Amazon S3 - // supported location constraints by Region, see Regions and Endpoints - // (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region). Buckets in - // Region us-east-1 have a LocationConstraint of null. + // supported location constraints by Region, see Regions and Endpoints (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) + // . Buckets in Region us-east-1 have a LocationConstraint of null . LocationConstraint types.BucketLocationConstraint // Metadata pertaining to the operation's result. @@ -87,6 +99,9 @@ func (c *Client) addOperationGetBucketLocationMiddlewares(stack *middleware.Stac if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -114,7 +129,7 @@ func (c *Client) addOperationGetBucketLocationMiddlewares(stack *middleware.Stac if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -129,6 +144,9 @@ func (c *Client) addOperationGetBucketLocationMiddlewares(stack *middleware.Stac if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketLocationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketLocationValidationMiddleware(stack); err != nil { return err } @@ -138,6 +156,9 @@ func (c *Client) addOperationGetBucketLocationMiddlewares(stack *middleware.Stac if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketLocationUpdateEndpoint(stack, options); err != nil { return err } @@ -153,6 +174,12 @@ func (c *Client) addOperationGetBucketLocationMiddlewares(stack *middleware.Stac if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } @@ -212,6 +239,13 @@ func swapDeserializerHelper(stack *middleware.Stack) error { return nil } +func (v *GetBucketLocationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketLocation(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -221,9 +255,9 @@ func newServiceMetadataMiddleware_opGetBucketLocation(region string) *awsmiddlew } } -// getGetBucketLocationBucketMember returns a pointer to string denoting a provided -// bucket member valueand a boolean indicating if the input has a modeled bucket -// name, +// getGetBucketLocationBucketMember returns a pointer to string denoting a +// provided bucket member valueand a boolean indicating if the input has a modeled +// bucket name, func getGetBucketLocationBucketMember(input interface{}) (*string, bool) { in := input.(*GetBucketLocationInput) if in.Bucket == nil { @@ -246,3 +280,139 @@ func addGetBucketLocationUpdateEndpoint(stack *middleware.Stack, options Options DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketLocationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketLocationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketLocationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketLocationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketLocationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketLocationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketLogging.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketLogging.go index ca115886d..13c01889c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketLogging.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketLogging.go @@ -4,24 +4,25 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns the logging status of a bucket and the permissions users have to view -// and modify that status. To use GET, you must be the bucket owner. The following -// operations are related to GetBucketLogging: -// -// * CreateBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) -// -// * -// PutBucketLogging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLogging.html) +// and modify that status. The following operations are related to GetBucketLogging +// : +// - CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) +// - PutBucketLogging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLogging.html) func (c *Client) GetBucketLogging(ctx context.Context, params *GetBucketLoggingInput, optFns ...func(*Options)) (*GetBucketLoggingOutput, error) { if params == nil { params = &GetBucketLoggingInput{} @@ -54,10 +55,9 @@ type GetBucketLoggingInput struct { type GetBucketLoggingOutput struct { - // Describes where logs are stored and the prefix that Amazon S3 assigns to all log - // object keys for a bucket. For more information, see PUT Bucket logging - // (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlogging.html) in - // the Amazon S3 API Reference. + // Describes where logs are stored and the prefix that Amazon S3 assigns to all + // log object keys for a bucket. For more information, see PUT Bucket logging (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlogging.html) + // in the Amazon S3 API Reference. LoggingEnabled *types.LoggingEnabled // Metadata pertaining to the operation's result. @@ -75,6 +75,9 @@ func (c *Client) addOperationGetBucketLoggingMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -102,7 +105,7 @@ func (c *Client) addOperationGetBucketLoggingMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -114,6 +117,9 @@ func (c *Client) addOperationGetBucketLoggingMiddlewares(stack *middleware.Stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketLoggingResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketLoggingValidationMiddleware(stack); err != nil { return err } @@ -123,6 +129,9 @@ func (c *Client) addOperationGetBucketLoggingMiddlewares(stack *middleware.Stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketLoggingUpdateEndpoint(stack, options); err != nil { return err } @@ -138,9 +147,22 @@ func (c *Client) addOperationGetBucketLoggingMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketLoggingInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketLogging(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -175,3 +197,139 @@ func addGetBucketLoggingUpdateEndpoint(stack *middleware.Stack, options Options) DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketLoggingResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketLoggingResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketLoggingResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketLoggingInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketLoggingResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketLoggingResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketMetricsConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketMetricsConfiguration.go index 22cf389cd..7755975da 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketMetricsConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketMetricsConfiguration.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -18,30 +24,15 @@ import ( // s3:GetMetricsConfiguration action. The bucket owner has this permission by // default. The bucket owner can grant this permission to others. For more // information about permissions, see Permissions Related to Bucket Subresource -// Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// For information about CloudWatch request metrics for Amazon S3, see Monitoring -// Metrics with Amazon CloudWatch -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html). -// The following operations are related to GetBucketMetricsConfiguration: -// -// * -// PutBucketMetricsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html) -// -// * -// DeleteBucketMetricsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html) -// -// * -// ListBucketMetricsConfigurations -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html) -// -// * -// Monitoring Metrics with Amazon CloudWatch -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html) +// Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . For information about CloudWatch request metrics for Amazon S3, see +// Monitoring Metrics with Amazon CloudWatch (https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html) +// . The following operations are related to GetBucketMetricsConfiguration : +// - PutBucketMetricsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html) +// - DeleteBucketMetricsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html) +// - ListBucketMetricsConfigurations (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html) +// - Monitoring Metrics with Amazon CloudWatch (https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html) func (c *Client) GetBucketMetricsConfiguration(ctx context.Context, params *GetBucketMetricsConfigurationInput, optFns ...func(*Options)) (*GetBucketMetricsConfigurationOutput, error) { if params == nil { params = &GetBucketMetricsConfigurationInput{} @@ -64,7 +55,8 @@ type GetBucketMetricsConfigurationInput struct { // This member is required. Bucket *string - // The ID used to identify the metrics configuration. + // The ID used to identify the metrics configuration. The ID has a 64 character + // limit and can only contain letters, numbers, periods, dashes, and underscores. // // This member is required. Id *string @@ -97,6 +89,9 @@ func (c *Client) addOperationGetBucketMetricsConfigurationMiddlewares(stack *mid if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -124,7 +119,7 @@ func (c *Client) addOperationGetBucketMetricsConfigurationMiddlewares(stack *mid if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -136,6 +131,9 @@ func (c *Client) addOperationGetBucketMetricsConfigurationMiddlewares(stack *mid if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketMetricsConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketMetricsConfigurationValidationMiddleware(stack); err != nil { return err } @@ -145,6 +143,9 @@ func (c *Client) addOperationGetBucketMetricsConfigurationMiddlewares(stack *mid if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketMetricsConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -160,9 +161,22 @@ func (c *Client) addOperationGetBucketMetricsConfigurationMiddlewares(stack *mid if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketMetricsConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketMetricsConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -197,3 +211,139 @@ func addGetBucketMetricsConfigurationUpdateEndpoint(stack *middleware.Stack, opt DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketMetricsConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketMetricsConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketMetricsConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketMetricsConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketMetricsConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketMetricsConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketNotificationConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketNotificationConfiguration.go index cbf103a7f..8d5eeb008 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketNotificationConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketNotificationConfiguration.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -17,16 +23,18 @@ import ( // element. By default, you must be the bucket owner to read the notification // configuration of a bucket. However, the bucket owner can use a bucket policy to // grant permission to other users to read this configuration with the -// s3:GetBucketNotification permission. For more information about setting and -// reading the notification configuration on a bucket, see Setting Up Notification -// of Bucket Events -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html). For -// more information about bucket policies, see Using Bucket Policies -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html). The -// following action is related to GetBucketNotification: -// -// * PutBucketNotification -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketNotification.html) +// s3:GetBucketNotification permission. To use this API operation against an access +// point, provide the alias of the access point in place of the bucket name. To use +// this API operation against an Object Lambda access point, provide the alias of +// the Object Lambda access point in place of the bucket name. If the Object Lambda +// access point alias in a request is not valid, the error code +// InvalidAccessPointAliasError is returned. For more information about +// InvalidAccessPointAliasError , see List of Error Codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) +// . For more information about setting and reading the notification configuration +// on a bucket, see Setting Up Notification of Bucket Events (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) +// . For more information about bucket policies, see Using Bucket Policies (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) +// . The following action is related to GetBucketNotification : +// - PutBucketNotification (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketNotification.html) func (c *Client) GetBucketNotificationConfiguration(ctx context.Context, params *GetBucketNotificationConfigurationInput, optFns ...func(*Options)) (*GetBucketNotificationConfigurationOutput, error) { if params == nil { params = &GetBucketNotificationConfigurationInput{} @@ -44,7 +52,14 @@ func (c *Client) GetBucketNotificationConfiguration(ctx context.Context, params type GetBucketNotificationConfigurationInput struct { - // The name of the bucket for which to get the notification configuration. + // The name of the bucket for which to get the notification configuration. To use + // this API operation against an access point, provide the alias of the access + // point in place of the bucket name. To use this API operation against an Object + // Lambda access point, provide the alias of the Object Lambda access point in + // place of the bucket name. If the Object Lambda access point alias in a request + // is not valid, the error code InvalidAccessPointAliasError is returned. For more + // information about InvalidAccessPointAliasError , see List of Error Codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) + // . // // This member is required. Bucket *string @@ -57,8 +72,8 @@ type GetBucketNotificationConfigurationInput struct { noSmithyDocumentSerde } -// A container for specifying the notification configuration of the bucket. If this -// element is empty, notifications are turned off for the bucket. +// A container for specifying the notification configuration of the bucket. If +// this element is empty, notifications are turned off for the bucket. type GetBucketNotificationConfigurationOutput struct { // Enables delivery of events to Amazon EventBridge. @@ -68,12 +83,12 @@ type GetBucketNotificationConfigurationOutput struct { // them. LambdaFunctionConfigurations []types.LambdaFunctionConfiguration - // The Amazon Simple Queue Service queues to publish messages to and the events for - // which to publish messages. + // The Amazon Simple Queue Service queues to publish messages to and the events + // for which to publish messages. QueueConfigurations []types.QueueConfiguration - // The topic to which notifications are sent and the events for which notifications - // are generated. + // The topic to which notifications are sent and the events for which + // notifications are generated. TopicConfigurations []types.TopicConfiguration // Metadata pertaining to the operation's result. @@ -91,6 +106,9 @@ func (c *Client) addOperationGetBucketNotificationConfigurationMiddlewares(stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -118,7 +136,7 @@ func (c *Client) addOperationGetBucketNotificationConfigurationMiddlewares(stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -130,6 +148,9 @@ func (c *Client) addOperationGetBucketNotificationConfigurationMiddlewares(stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketNotificationConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketNotificationConfigurationValidationMiddleware(stack); err != nil { return err } @@ -139,6 +160,9 @@ func (c *Client) addOperationGetBucketNotificationConfigurationMiddlewares(stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketNotificationConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -154,9 +178,22 @@ func (c *Client) addOperationGetBucketNotificationConfigurationMiddlewares(stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketNotificationConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketNotificationConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -191,3 +228,139 @@ func addGetBucketNotificationConfigurationUpdateEndpoint(stack *middleware.Stack DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketNotificationConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketNotificationConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketNotificationConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketNotificationConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketNotificationConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketNotificationConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketOwnershipControls.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketOwnershipControls.go index 571c9566c..125c3e14f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketOwnershipControls.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketOwnershipControls.go @@ -4,26 +4,27 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Retrieves OwnershipControls for an Amazon S3 bucket. To use this operation, you // must have the s3:GetBucketOwnershipControls permission. For more information -// about Amazon S3 permissions, see Specifying permissions in a policy -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html). -// For information about Amazon S3 Object Ownership, see Using Object Ownership -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html). -// The following operations are related to GetBucketOwnershipControls: -// -// * -// PutBucketOwnershipControls -// -// * DeleteBucketOwnershipControls +// about Amazon S3 permissions, see Specifying permissions in a policy (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html) +// . For information about Amazon S3 Object Ownership, see Using Object Ownership (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) +// . The following operations are related to GetBucketOwnershipControls : +// - PutBucketOwnershipControls +// - DeleteBucketOwnershipControls func (c *Client) GetBucketOwnershipControls(ctx context.Context, params *GetBucketOwnershipControlsInput, optFns ...func(*Options)) (*GetBucketOwnershipControlsOutput, error) { if params == nil { params = &GetBucketOwnershipControlsInput{} @@ -75,6 +76,9 @@ func (c *Client) addOperationGetBucketOwnershipControlsMiddlewares(stack *middle if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -102,7 +106,7 @@ func (c *Client) addOperationGetBucketOwnershipControlsMiddlewares(stack *middle if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -114,6 +118,9 @@ func (c *Client) addOperationGetBucketOwnershipControlsMiddlewares(stack *middle if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketOwnershipControlsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketOwnershipControlsValidationMiddleware(stack); err != nil { return err } @@ -123,6 +130,9 @@ func (c *Client) addOperationGetBucketOwnershipControlsMiddlewares(stack *middle if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketOwnershipControlsUpdateEndpoint(stack, options); err != nil { return err } @@ -138,9 +148,22 @@ func (c *Client) addOperationGetBucketOwnershipControlsMiddlewares(stack *middle if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketOwnershipControlsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketOwnershipControls(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -150,9 +173,9 @@ func newServiceMetadataMiddleware_opGetBucketOwnershipControls(region string) *a } } -// getGetBucketOwnershipControlsBucketMember returns a pointer to string denoting a -// provided bucket member valueand a boolean indicating if the input has a modeled -// bucket name, +// getGetBucketOwnershipControlsBucketMember returns a pointer to string denoting +// a provided bucket member valueand a boolean indicating if the input has a +// modeled bucket name, func getGetBucketOwnershipControlsBucketMember(input interface{}) (*string, bool) { in := input.(*GetBucketOwnershipControlsInput) if in.Bucket == nil { @@ -175,3 +198,139 @@ func addGetBucketOwnershipControlsUpdateEndpoint(stack *middleware.Stack, option DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketOwnershipControlsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketOwnershipControlsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketOwnershipControlsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketOwnershipControlsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketOwnershipControlsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketOwnershipControlsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketPolicy.go index f16c84cdd..d167fc45b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketPolicy.go @@ -4,9 +4,15 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -18,16 +24,23 @@ import ( // If you don't have GetBucketPolicy permissions, Amazon S3 returns a 403 Access // Denied error. If you have the correct permissions, but you're not using an // identity that belongs to the bucket owner's account, Amazon S3 returns a 405 -// Method Not Allowed error. As a security precaution, the root user of the Amazon -// Web Services account that owns a bucket can always use this operation, even if -// the policy explicitly denies the root user the ability to perform this action. -// For more information about bucket policies, see Using Bucket Policies and User -// Policies -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html). The -// following action is related to GetBucketPolicy: -// -// * GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// Method Not Allowed error. To ensure that bucket owners don't inadvertently lock +// themselves out of their own buckets, the root principal in a bucket owner's +// Amazon Web Services account can perform the GetBucketPolicy , PutBucketPolicy , +// and DeleteBucketPolicy API actions, even if their bucket policy explicitly +// denies the root principal's access. Bucket owner root principals can only be +// blocked from performing these API actions by VPC endpoint policies and Amazon +// Web Services Organizations policies. To use this API operation against an access +// point, provide the alias of the access point in place of the bucket name. To use +// this API operation against an Object Lambda access point, provide the alias of +// the Object Lambda access point in place of the bucket name. If the Object Lambda +// access point alias in a request is not valid, the error code +// InvalidAccessPointAliasError is returned. For more information about +// InvalidAccessPointAliasError , see List of Error Codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) +// . For more information about bucket policies, see Using Bucket Policies and +// User Policies (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) +// . The following action is related to GetBucketPolicy : +// - GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) func (c *Client) GetBucketPolicy(ctx context.Context, params *GetBucketPolicyInput, optFns ...func(*Options)) (*GetBucketPolicyOutput, error) { if params == nil { params = &GetBucketPolicyInput{} @@ -45,7 +58,14 @@ func (c *Client) GetBucketPolicy(ctx context.Context, params *GetBucketPolicyInp type GetBucketPolicyInput struct { - // The bucket name for which to get the bucket policy. + // The bucket name for which to get the bucket policy. To use this API operation + // against an access point, provide the alias of the access point in place of the + // bucket name. To use this API operation against an Object Lambda access point, + // provide the alias of the Object Lambda access point in place of the bucket name. + // If the Object Lambda access point alias in a request is not valid, the error + // code InvalidAccessPointAliasError is returned. For more information about + // InvalidAccessPointAliasError , see List of Error Codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) + // . // // This member is required. Bucket *string @@ -78,6 +98,9 @@ func (c *Client) addOperationGetBucketPolicyMiddlewares(stack *middleware.Stack, if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -105,7 +128,7 @@ func (c *Client) addOperationGetBucketPolicyMiddlewares(stack *middleware.Stack, if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -117,6 +140,9 @@ func (c *Client) addOperationGetBucketPolicyMiddlewares(stack *middleware.Stack, if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketPolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketPolicyValidationMiddleware(stack); err != nil { return err } @@ -126,6 +152,9 @@ func (c *Client) addOperationGetBucketPolicyMiddlewares(stack *middleware.Stack, if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketPolicyUpdateEndpoint(stack, options); err != nil { return err } @@ -141,9 +170,22 @@ func (c *Client) addOperationGetBucketPolicyMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketPolicyInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketPolicy(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -178,3 +220,139 @@ func addGetBucketPolicyUpdateEndpoint(stack *middleware.Stack, options Options) DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketPolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketPolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketPolicyResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketPolicyInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketPolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketPolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketPolicyStatus.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketPolicyStatus.go index 570f60faa..8229d4f48 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketPolicyStatus.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketPolicyStatus.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -15,28 +21,14 @@ import ( // Retrieves the policy status for an Amazon S3 bucket, indicating whether the // bucket is public. In order to use this operation, you must have the // s3:GetBucketPolicyStatus permission. For more information about Amazon S3 -// permissions, see Specifying Permissions in a Policy -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html). -// For more information about when Amazon S3 considers a bucket public, see The -// Meaning of "Public" -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html#access-control-block-public-access-policy-status). -// The following operations are related to GetBucketPolicyStatus: -// -// * Using Amazon -// S3 Block Public Access -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html) -// -// * -// GetPublicAccessBlock -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetPublicAccessBlock.html) -// -// * -// PutPublicAccessBlock -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutPublicAccessBlock.html) -// -// * -// DeletePublicAccessBlock -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeletePublicAccessBlock.html) +// permissions, see Specifying Permissions in a Policy (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html) +// . For more information about when Amazon S3 considers a bucket public, see The +// Meaning of "Public" (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html#access-control-block-public-access-policy-status) +// . The following operations are related to GetBucketPolicyStatus : +// - Using Amazon S3 Block Public Access (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html) +// - GetPublicAccessBlock (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetPublicAccessBlock.html) +// - PutPublicAccessBlock (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutPublicAccessBlock.html) +// - DeletePublicAccessBlock (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeletePublicAccessBlock.html) func (c *Client) GetBucketPolicyStatus(ctx context.Context, params *GetBucketPolicyStatusInput, optFns ...func(*Options)) (*GetBucketPolicyStatusOutput, error) { if params == nil { params = &GetBucketPolicyStatusInput{} @@ -87,6 +79,9 @@ func (c *Client) addOperationGetBucketPolicyStatusMiddlewares(stack *middleware. if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -114,7 +109,7 @@ func (c *Client) addOperationGetBucketPolicyStatusMiddlewares(stack *middleware. if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -126,6 +121,9 @@ func (c *Client) addOperationGetBucketPolicyStatusMiddlewares(stack *middleware. if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketPolicyStatusResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketPolicyStatusValidationMiddleware(stack); err != nil { return err } @@ -135,6 +133,9 @@ func (c *Client) addOperationGetBucketPolicyStatusMiddlewares(stack *middleware. if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketPolicyStatusUpdateEndpoint(stack, options); err != nil { return err } @@ -150,9 +151,22 @@ func (c *Client) addOperationGetBucketPolicyStatusMiddlewares(stack *middleware. if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketPolicyStatusInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketPolicyStatus(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -187,3 +201,139 @@ func addGetBucketPolicyStatusUpdateEndpoint(stack *middleware.Stack, options Opt DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketPolicyStatusResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketPolicyStatusResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketPolicyStatusResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketPolicyStatusInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketPolicyStatusResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketPolicyStatusResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketReplication.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketReplication.go index 5d7f3115b..5cf7567ac 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketReplication.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketReplication.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -15,26 +21,17 @@ import ( // Returns the replication configuration of a bucket. It can take a while to // propagate the put or delete a replication configuration to all Amazon S3 // systems. Therefore, a get request soon after put or delete can return a wrong -// result. For information about replication configuration, see Replication -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication.html) in the Amazon -// S3 User Guide. This action requires permissions for the +// result. For information about replication configuration, see Replication (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication.html) +// in the Amazon S3 User Guide. This action requires permissions for the // s3:GetReplicationConfiguration action. For more information about permissions, -// see Using Bucket Policies and User Policies -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html). If -// you include the Filter element in a replication configuration, you must also -// include the DeleteMarkerReplication and Priority elements. The response also -// returns those elements. For information about GetBucketReplication errors, see -// List of replication-related error codes -// (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ReplicationErrorCodeList) -// The following operations are related to GetBucketReplication: -// -// * -// PutBucketReplication -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketReplication.html) -// -// * -// DeleteBucketReplication -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketReplication.html) +// see Using Bucket Policies and User Policies (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) +// . If you include the Filter element in a replication configuration, you must +// also include the DeleteMarkerReplication and Priority elements. The response +// also returns those elements. For information about GetBucketReplication errors, +// see List of replication-related error codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ReplicationErrorCodeList) +// The following operations are related to GetBucketReplication : +// - PutBucketReplication (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketReplication.html) +// - DeleteBucketReplication (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketReplication.html) func (c *Client) GetBucketReplication(ctx context.Context, params *GetBucketReplicationInput, optFns ...func(*Options)) (*GetBucketReplicationOutput, error) { if params == nil { params = &GetBucketReplicationInput{} @@ -86,6 +83,9 @@ func (c *Client) addOperationGetBucketReplicationMiddlewares(stack *middleware.S if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -113,7 +113,7 @@ func (c *Client) addOperationGetBucketReplicationMiddlewares(stack *middleware.S if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -125,6 +125,9 @@ func (c *Client) addOperationGetBucketReplicationMiddlewares(stack *middleware.S if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketReplicationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketReplicationValidationMiddleware(stack); err != nil { return err } @@ -134,6 +137,9 @@ func (c *Client) addOperationGetBucketReplicationMiddlewares(stack *middleware.S if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketReplicationUpdateEndpoint(stack, options); err != nil { return err } @@ -149,9 +155,22 @@ func (c *Client) addOperationGetBucketReplicationMiddlewares(stack *middleware.S if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketReplicationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketReplication(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -186,3 +205,139 @@ func addGetBucketReplicationUpdateEndpoint(stack *middleware.Stack, options Opti DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketReplicationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketReplicationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketReplicationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketReplicationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketReplicationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketReplicationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketRequestPayment.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketRequestPayment.go index 45f985b95..14a9883cc 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketRequestPayment.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketRequestPayment.go @@ -4,22 +4,25 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns the request payment configuration of a bucket. To use this version of -// the operation, you must be the bucket owner. For more information, see Requester -// Pays Buckets -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/RequesterPaysBuckets.html). The -// following operations are related to GetBucketRequestPayment: -// -// * ListObjects -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html) +// the operation, you must be the bucket owner. For more information, see +// Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/RequesterPaysBuckets.html) +// . The following operations are related to GetBucketRequestPayment : +// - ListObjects (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html) func (c *Client) GetBucketRequestPayment(ctx context.Context, params *GetBucketRequestPaymentInput, optFns ...func(*Options)) (*GetBucketRequestPaymentOutput, error) { if params == nil { params = &GetBucketRequestPaymentInput{} @@ -70,6 +73,9 @@ func (c *Client) addOperationGetBucketRequestPaymentMiddlewares(stack *middlewar if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -97,7 +103,7 @@ func (c *Client) addOperationGetBucketRequestPaymentMiddlewares(stack *middlewar if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -109,6 +115,9 @@ func (c *Client) addOperationGetBucketRequestPaymentMiddlewares(stack *middlewar if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketRequestPaymentResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketRequestPaymentValidationMiddleware(stack); err != nil { return err } @@ -118,6 +127,9 @@ func (c *Client) addOperationGetBucketRequestPaymentMiddlewares(stack *middlewar if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketRequestPaymentUpdateEndpoint(stack, options); err != nil { return err } @@ -133,9 +145,22 @@ func (c *Client) addOperationGetBucketRequestPaymentMiddlewares(stack *middlewar if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketRequestPaymentInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketRequestPayment(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -170,3 +195,139 @@ func addGetBucketRequestPaymentUpdateEndpoint(stack *middleware.Stack, options O DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketRequestPaymentResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketRequestPaymentResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketRequestPaymentResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketRequestPaymentInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketRequestPaymentResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketRequestPaymentResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketTagging.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketTagging.go index 816d1b3e7..a2cd2bb66 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketTagging.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketTagging.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -16,21 +22,12 @@ import ( // have permission to perform the s3:GetBucketTagging action. By default, the // bucket owner has this permission and can grant this permission to others. // GetBucketTagging has the following special error: +// - Error code: NoSuchTagSet +// - Description: There is no tag set associated with the bucket. // -// * Error code: NoSuchTagSet -// -// * -// Description: There is no tag set associated with the bucket. -// -// The following -// operations are related to GetBucketTagging: -// -// * PutBucketTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketTagging.html) -// -// * -// DeleteBucketTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketTagging.html) +// The following operations are related to GetBucketTagging : +// - PutBucketTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketTagging.html) +// - DeleteBucketTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketTagging.html) func (c *Client) GetBucketTagging(ctx context.Context, params *GetBucketTaggingInput, optFns ...func(*Options)) (*GetBucketTaggingOutput, error) { if params == nil { params = &GetBucketTaggingInput{} @@ -83,6 +80,9 @@ func (c *Client) addOperationGetBucketTaggingMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -110,7 +110,7 @@ func (c *Client) addOperationGetBucketTaggingMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -122,6 +122,9 @@ func (c *Client) addOperationGetBucketTaggingMiddlewares(stack *middleware.Stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketTaggingResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketTaggingValidationMiddleware(stack); err != nil { return err } @@ -131,6 +134,9 @@ func (c *Client) addOperationGetBucketTaggingMiddlewares(stack *middleware.Stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketTaggingUpdateEndpoint(stack, options); err != nil { return err } @@ -146,9 +152,22 @@ func (c *Client) addOperationGetBucketTaggingMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketTaggingInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketTagging(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -183,3 +202,139 @@ func addGetBucketTaggingUpdateEndpoint(stack *middleware.Stack, options Options) DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketTaggingResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketTaggingResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketTaggingResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketTaggingInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketTaggingResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketTaggingResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketVersioning.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketVersioning.go index 3657bd1ca..3153eaa76 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketVersioning.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketVersioning.go @@ -4,31 +4,28 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns the versioning state of a bucket. To retrieve the versioning state of a // bucket, you must be the bucket owner. This implementation also returns the MFA -// Delete status of the versioning state. If the MFA Delete status is enabled, the +// Delete status of the versioning state. If the MFA Delete status is enabled , the // bucket owner must use an authentication device to change the versioning state of -// the bucket. The following operations are related to GetBucketVersioning: -// -// * -// GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) -// -// * -// PutObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) -// -// * -// DeleteObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) +// the bucket. The following operations are related to GetBucketVersioning : +// - GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// - PutObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) +// - DeleteObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) func (c *Client) GetBucketVersioning(ctx context.Context, params *GetBucketVersioningInput, optFns ...func(*Options)) (*GetBucketVersioningOutput, error) { if params == nil { params = &GetBucketVersioningInput{} @@ -84,6 +81,9 @@ func (c *Client) addOperationGetBucketVersioningMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -111,7 +111,7 @@ func (c *Client) addOperationGetBucketVersioningMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -123,6 +123,9 @@ func (c *Client) addOperationGetBucketVersioningMiddlewares(stack *middleware.St if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketVersioningResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketVersioningValidationMiddleware(stack); err != nil { return err } @@ -132,6 +135,9 @@ func (c *Client) addOperationGetBucketVersioningMiddlewares(stack *middleware.St if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketVersioningUpdateEndpoint(stack, options); err != nil { return err } @@ -147,9 +153,22 @@ func (c *Client) addOperationGetBucketVersioningMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketVersioningInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketVersioning(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -184,3 +203,139 @@ func addGetBucketVersioningUpdateEndpoint(stack *middleware.Stack, options Optio DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketVersioningResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketVersioningResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketVersioningResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketVersioningInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketVersioningResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketVersioningResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketWebsite.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketWebsite.go index aa866b301..c28296a6c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketWebsite.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetBucketWebsite.go @@ -4,30 +4,30 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns the website configuration for a bucket. To host website on Amazon S3, // you can configure a bucket as website by adding a website configuration. For -// more information about hosting websites, see Hosting Websites on Amazon S3 -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html). This GET -// action requires the S3:GetBucketWebsite permission. By default, only the bucket -// owner can read the bucket website configuration. However, bucket owners can -// allow other users to read the website configuration by writing a bucket policy -// granting them the S3:GetBucketWebsite permission. The following operations are -// related to DeleteBucketWebsite: -// -// * DeleteBucketWebsite -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketWebsite.html) -// -// * -// PutBucketWebsite -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketWebsite.html) +// more information about hosting websites, see Hosting Websites on Amazon S3 (https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html) +// . This GET action requires the S3:GetBucketWebsite permission. By default, only +// the bucket owner can read the bucket website configuration. However, bucket +// owners can allow other users to read the website configuration by writing a +// bucket policy granting them the S3:GetBucketWebsite permission. The following +// operations are related to GetBucketWebsite : +// - DeleteBucketWebsite (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketWebsite.html) +// - PutBucketWebsite (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketWebsite.html) func (c *Client) GetBucketWebsite(ctx context.Context, params *GetBucketWebsiteInput, optFns ...func(*Options)) (*GetBucketWebsiteOutput, error) { if params == nil { params = &GetBucketWebsiteInput{} @@ -63,7 +63,7 @@ type GetBucketWebsiteOutput struct { // The object key name of the website error document to use for 4XX class errors. ErrorDocument *types.ErrorDocument - // The name of the index document for the website (for example index.html). + // The name of the index document for the website (for example index.html ). IndexDocument *types.IndexDocument // Specifies the redirect behavior of all requests to a website endpoint of an @@ -88,6 +88,9 @@ func (c *Client) addOperationGetBucketWebsiteMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -115,7 +118,7 @@ func (c *Client) addOperationGetBucketWebsiteMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -127,6 +130,9 @@ func (c *Client) addOperationGetBucketWebsiteMiddlewares(stack *middleware.Stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetBucketWebsiteResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetBucketWebsiteValidationMiddleware(stack); err != nil { return err } @@ -136,6 +142,9 @@ func (c *Client) addOperationGetBucketWebsiteMiddlewares(stack *middleware.Stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetBucketWebsiteUpdateEndpoint(stack, options); err != nil { return err } @@ -151,9 +160,22 @@ func (c *Client) addOperationGetBucketWebsiteMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetBucketWebsiteInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetBucketWebsite(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -188,3 +210,139 @@ func addGetBucketWebsiteUpdateEndpoint(stack *middleware.Stack, options Options) DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetBucketWebsiteResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetBucketWebsiteResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetBucketWebsiteResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetBucketWebsiteInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetBucketWebsiteResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetBucketWebsiteResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObject.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObject.go index 92c38bed8..e84be49a9 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObject.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObject.go @@ -4,97 +4,83 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "io" "time" ) -// Retrieves objects from Amazon S3. To use GET, you must have READ access to the +// Retrieves objects from Amazon S3. To use GET , you must have READ access to the // object. If you grant READ access to the anonymous user, you can return the // object without using an authorization header. An Amazon S3 bucket has no // directory hierarchy such as you would find in a typical computer file system. // You can, however, create a logical hierarchy by using object key names that -// imply a folder structure. For example, instead of naming an object sample.jpg, -// you can name it photos/2006/February/sample.jpg. To get an object from such a +// imply a folder structure. For example, instead of naming an object sample.jpg , +// you can name it photos/2006/February/sample.jpg . To get an object from such a // logical hierarchy, specify the full key name for the object in the GET // operation. For a virtual hosted-style request example, if you have the object -// photos/2006/February/sample.jpg, specify the resource as -// /photos/2006/February/sample.jpg. For a path-style request example, if you have -// the object photos/2006/February/sample.jpg in the bucket named examplebucket, -// specify the resource as /examplebucket/photos/2006/February/sample.jpg. For more -// information about request types, see HTTP Host Header Bucket Specification -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html#VirtualHostingSpecifyBucket). -// For more information about returning the ACL of an object, see GetObjectAcl -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html). If the -// object you are retrieving is stored in the S3 Glacier or S3 Glacier Deep Archive -// storage class, or S3 Intelligent-Tiering Archive or S3 Intelligent-Tiering Deep -// Archive tiers, before you can retrieve the object you must first restore a copy -// using RestoreObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_RestoreObject.html). -// Otherwise, this action returns an InvalidObjectStateError error. For information -// about restoring archived objects, see Restoring Archived Objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/restoring-objects.html). -// Encryption request headers, like x-amz-server-side-encryption, should not be -// sent for GET requests if your object uses server-side encryption with KMS keys -// (SSE-KMS) or server-side encryption with Amazon S3–managed encryption keys -// (SSE-S3). If your object does use these types of keys, you’ll get an HTTP 400 -// BadRequest error. If you encrypt an object by using server-side encryption with -// customer-provided encryption keys (SSE-C) when you store the object in Amazon -// S3, then when you GET the object, you must use the following headers: +// photos/2006/February/sample.jpg , specify the resource as +// /photos/2006/February/sample.jpg . For a path-style request example, if you have +// the object photos/2006/February/sample.jpg in the bucket named examplebucket , +// specify the resource as /examplebucket/photos/2006/February/sample.jpg . For +// more information about request types, see HTTP Host Header Bucket Specification (https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html#VirtualHostingSpecifyBucket) +// . For more information about returning the ACL of an object, see GetObjectAcl (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html) +// . If the object you are retrieving is stored in the S3 Glacier Flexible +// Retrieval or S3 Glacier Deep Archive storage class, or S3 Intelligent-Tiering +// Archive or S3 Intelligent-Tiering Deep Archive tiers, before you can retrieve +// the object you must first restore a copy using RestoreObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_RestoreObject.html) +// . Otherwise, this action returns an InvalidObjectState error. For information +// about restoring archived objects, see Restoring Archived Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/restoring-objects.html) +// . Encryption request headers, like x-amz-server-side-encryption , should not be +// sent for GET requests if your object uses server-side encryption with Key +// Management Service (KMS) keys (SSE-KMS), dual-layer server-side encryption with +// Amazon Web Services KMS keys (DSSE-KMS), or server-side encryption with Amazon +// S3 managed encryption keys (SSE-S3). If your object does use these types of +// keys, you’ll get an HTTP 400 Bad Request error. If you encrypt an object by +// using server-side encryption with customer-provided encryption keys (SSE-C) when +// you store the object in Amazon S3, then when you GET the object, you must use +// the following headers: +// - x-amz-server-side-encryption-customer-algorithm +// - x-amz-server-side-encryption-customer-key +// - x-amz-server-side-encryption-customer-key-MD5 // -// * -// x-amz-server-side-encryption-customer-algorithm -// -// * -// x-amz-server-side-encryption-customer-key -// -// * -// x-amz-server-side-encryption-customer-key-MD5 -// -// For more information about SSE-C, -// see Server-Side Encryption (Using Customer-Provided Encryption Keys) -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html). -// Assuming you have the relevant permission to read object tags, the response also -// returns the x-amz-tagging-count header that provides the count of number of tags -// associated with the object. You can use GetObjectTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html) to -// retrieve the tag set associated with an object. Permissions You need the +// For more information about SSE-C, see Server-Side Encryption (Using +// Customer-Provided Encryption Keys) (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) +// . Assuming you have the relevant permission to read object tags, the response +// also returns the x-amz-tagging-count header that provides the count of number +// of tags associated with the object. You can use GetObjectTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html) +// to retrieve the tag set associated with an object. Permissions You need the // relevant read object (or version) permission for this operation. For more -// information, see Specifying Permissions in a Policy -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html). If -// the object you request does not exist, the error Amazon S3 returns depends on -// whether you also have the s3:ListBucket permission. -// -// * If you have the -// s3:ListBucket permission on the bucket, Amazon S3 will return an HTTP status -// code 404 ("no such key") error. -// -// * If you don’t have the s3:ListBucket -// permission, Amazon S3 will return an HTTP status code 403 ("access denied") -// error. -// -// Versioning By default, the GET action returns the current version of an -// object. To return a different version, use the versionId subresource. -// -// * If you -// supply a versionId, you need the s3:GetObjectVersion permission to access a -// specific version of an object. If you request a specific version, you do not -// need to have the s3:GetObject permission. -// -// * If the current version of the -// object is a delete marker, Amazon S3 behaves as if the object was deleted and -// includes x-amz-delete-marker: true in the response. +// information, see Specifying Permissions in a Policy (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html) +// . If the object that you request doesn’t exist, the error that Amazon S3 returns +// depends on whether you also have the s3:ListBucket permission. If you have the +// s3:ListBucket permission on the bucket, Amazon S3 returns an HTTP status code +// 404 (Not Found) error. If you don’t have the s3:ListBucket permission, Amazon +// S3 returns an HTTP status code 403 ("access denied") error. Versioning By +// default, the GET action returns the current version of an object. To return a +// different version, use the versionId subresource. +// - If you supply a versionId , you need the s3:GetObjectVersion permission to +// access a specific version of an object. If you request a specific version, you +// do not need to have the s3:GetObject permission. If you request the current +// version without a specific version ID, only s3:GetObject permission is +// required. s3:GetObjectVersion permission won't be required. +// - If the current version of the object is a delete marker, Amazon S3 behaves +// as if the object was deleted and includes x-amz-delete-marker: true in the +// response. // -// For more information about -// versioning, see PutBucketVersioning -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketVersioning.html). -// Overriding Response Header Values There are times when you want to override +// For more information about versioning, see PutBucketVersioning (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketVersioning.html) +// . Overriding Response Header Values There are times when you want to override // certain response header values in a GET response. For example, you might // override the Content-Disposition response header value in your GET request. You // can override values for a set of response headers using the following query @@ -102,44 +88,30 @@ import ( // that is, when status code 200 OK is returned. The set of headers you can // override using these parameters is a subset of the headers that Amazon S3 // accepts when you create an object. The response headers that you can override -// for the GET response are Content-Type, Content-Language, Expires, Cache-Control, -// Content-Disposition, and Content-Encoding. To override these header values in -// the GET response, you use the following request parameters. You must sign the -// request, either using an Authorization header or a presigned URL, when using -// these parameters. They cannot be used with an unsigned (anonymous) request. -// -// * -// response-content-type -// -// * response-content-language -// -// * response-expires -// -// * -// response-cache-control -// -// * response-content-disposition -// -// * -// response-content-encoding -// -// Additional Considerations about Request Headers If -// both of the If-Match and If-Unmodified-Since headers are present in the request -// as follows: If-Match condition evaluates to true, and; If-Unmodified-Since -// condition evaluates to false; then, S3 returns 200 OK and the data requested. If -// both of the If-None-Match and If-Modified-Since headers are present in the -// request as follows: If-None-Match condition evaluates to false, and; -// If-Modified-Since condition evaluates to true; then, S3 returns 304 Not Modified -// response code. For more information about conditional requests, see RFC 7232 -// (https://tools.ietf.org/html/rfc7232). The following operations are related to -// GetObject: -// -// * ListBuckets -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html) +// for the GET response are Content-Type , Content-Language , Expires , +// Cache-Control , Content-Disposition , and Content-Encoding . To override these +// header values in the GET response, you use the following request parameters. +// You must sign the request, either using an Authorization header or a presigned +// URL, when using these parameters. They cannot be used with an unsigned +// (anonymous) request. +// - response-content-type +// - response-content-language +// - response-expires +// - response-cache-control +// - response-content-disposition +// - response-content-encoding // -// * -// GetObjectAcl -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html) +// Overriding Response Header Values If both of the If-Match and +// If-Unmodified-Since headers are present in the request as follows: If-Match +// condition evaluates to true , and; If-Unmodified-Since condition evaluates to +// false ; then, S3 returns 200 OK and the data requested. If both of the +// If-None-Match and If-Modified-Since headers are present in the request as +// follows: If-None-Match condition evaluates to false , and; If-Modified-Since +// condition evaluates to true ; then, S3 returns 304 Not Modified response code. +// For more information about conditional requests, see RFC 7232 (https://tools.ietf.org/html/rfc7232) +// . The following operations are related to GetObject : +// - ListBuckets (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html) +// - GetObjectAcl (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html) func (c *Client) GetObject(ctx context.Context, params *GetObjectInput, optFns ...func(*Options)) (*GetObjectOutput, error) { if params == nil { params = &GetObjectInput{} @@ -163,19 +135,17 @@ type GetObjectInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) // in the Amazon S3 User Guide. When using an Object Lambda access point the // hostname takes the form - // AccessPointName-AccountId.s3-object-lambda.Region.amazonaws.com. When using this - // action with Amazon S3 on Outposts, you must direct requests to the S3 on + // AccessPointName-AccountId.s3-object-lambda.Region.amazonaws.com. When you use + // this action with Amazon S3 on Outposts, you must direct requests to the S3 on // Outposts hostname. The S3 on Outposts hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -214,18 +184,18 @@ type GetObjectInput struct { // Useful for downloading just a part of an object. PartNumber int32 - // Downloads the specified range bytes of an object. For more information about the - // HTTP Range header, see - // https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 - // (https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35). Amazon S3 - // doesn't support retrieving multiple ranges of data per GET request. + // Downloads the specified range bytes of an object. For more information about + // the HTTP Range header, see + // https://www.rfc-editor.org/rfc/rfc9110.html#name-range (https://www.rfc-editor.org/rfc/rfc9110.html#name-range) + // . Amazon S3 doesn't support retrieving multiple ranges of data per GET request. Range *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -251,11 +221,11 @@ type GetObjectInput struct { // AES256). SSECustomerAlgorithm *string - // Specifies the customer-provided encryption key for Amazon S3 used to encrypt the - // data. This value is used to decrypt the object when recovering it and must match - // the one used when storing the data. The key must be appropriate for use with the - // algorithm specified in the x-amz-server-side-encryption-customer-algorithm - // header. + // Specifies the customer-provided encryption key for Amazon S3 used to encrypt + // the data. This value is used to decrypt the object when recovering it and must + // match the one used when storing the data. The key must be appropriate for use + // with the algorithm specified in the + // x-amz-server-side-encryption-customer-algorithm header. SSECustomerKey *string // Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321. @@ -278,7 +248,7 @@ type GetObjectOutput struct { Body io.ReadCloser // Indicates whether the object uses an S3 Bucket Key for server-side encryption - // with Amazon Web Services KMS (SSE-KMS). + // with Key Management Service (KMS) keys (SSE-KMS). BucketKeyEnabled bool // Specifies caching behavior along the request/reply chain. @@ -287,32 +257,28 @@ type GetObjectOutput struct { // The base64-encoded, 32-bit CRC32 checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32 *string // The base64-encoded, 32-bit CRC32C checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32C *string // The base64-encoded, 160-bit SHA-1 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA1 *string // The base64-encoded, 256-bit SHA-256 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA256 *string @@ -393,22 +359,22 @@ type GetObjectOutput struct { // restored object copy. Restore *string - // If server-side encryption with a customer-provided encryption key was requested, - // the response will include this header confirming the encryption algorithm used. + // If server-side encryption with a customer-provided encryption key was + // requested, the response will include this header confirming the encryption + // algorithm used. SSECustomerAlgorithm *string - // If server-side encryption with a customer-provided encryption key was requested, - // the response will include this header to provide round-trip message integrity - // verification of the customer-provided encryption key. + // If server-side encryption with a customer-provided encryption key was + // requested, the response will include this header to provide round-trip message + // integrity verification of the customer-provided encryption key. SSECustomerKeyMD5 *string - // If present, specifies the ID of the Amazon Web Services Key Management Service - // (Amazon Web Services KMS) symmetric customer managed key that was used for the - // object. + // If present, specifies the ID of the Key Management Service (KMS) symmetric + // encryption customer managed key that was used for the object. SSEKMSKeyId *string // The server-side encryption algorithm used when storing this object in Amazon S3 - // (for example, AES256, aws:kms). + // (for example, AES256 , aws:kms , aws:kms:dsse ). ServerSideEncryption types.ServerSideEncryption // Provides storage class information of the object. Amazon S3 returns this header @@ -441,6 +407,9 @@ func (c *Client) addOperationGetObjectMiddlewares(stack *middleware.Stack, optio if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -468,7 +437,7 @@ func (c *Client) addOperationGetObjectMiddlewares(stack *middleware.Stack, optio if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -477,6 +446,9 @@ func (c *Client) addOperationGetObjectMiddlewares(stack *middleware.Stack, optio if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetObjectResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetObjectValidationMiddleware(stack); err != nil { return err } @@ -486,6 +458,9 @@ func (c *Client) addOperationGetObjectMiddlewares(stack *middleware.Stack, optio if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetObjectOutputChecksumMiddlewares(stack, options); err != nil { return err } @@ -504,9 +479,22 @@ func (c *Client) addOperationGetObjectMiddlewares(stack *middleware.Stack, optio if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetObjectInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetObject(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -591,3 +579,139 @@ func addGetObjectPayloadAsUnsigned(stack *middleware.Stack, options Options) err v4.RemoveComputePayloadSHA256Middleware(stack) return v4.AddUnsignedPayloadMiddleware(stack) } + +type opGetObjectResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetObjectResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetObjectResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetObjectInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetObjectResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetObjectResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectAcl.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectAcl.go index 709e62ff7..b6ea63ea0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectAcl.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectAcl.go @@ -4,43 +4,37 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns the access control list (ACL) of an object. To use this operation, you -// must have s3:GetObjectAcl permissions or READ_ACP access to the object. For more -// information, see Mapping of ACL permissions and access policy permissions -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#acl-access-policy-permission-mapping) +// must have s3:GetObjectAcl permissions or READ_ACP access to the object. For +// more information, see Mapping of ACL permissions and access policy permissions (https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#acl-access-policy-permission-mapping) // in the Amazon S3 User Guide This action is not supported by Amazon S3 on -// Outposts. Versioning By default, GET returns ACL information about the current -// version of an object. To return ACL information about a different version, use -// the versionId subresource. If your bucket uses the bucket owner enforced setting -// for S3 Object Ownership, requests to read ACLs are still supported and return -// the bucket-owner-full-control ACL with the owner being the account that created -// the bucket. For more information, see Controlling object ownership and -// disabling ACLs -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) +// Outposts. By default, GET returns ACL information about the current version of +// an object. To return ACL information about a different version, use the +// versionId subresource. If your bucket uses the bucket owner enforced setting for +// S3 Object Ownership, requests to read ACLs are still supported and return the +// bucket-owner-full-control ACL with the owner being the account that created the +// bucket. For more information, see Controlling object ownership and disabling +// ACLs (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) // in the Amazon S3 User Guide. The following operations are related to -// GetObjectAcl: -// -// * GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) -// -// * -// GetObjectAttributes -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) -// -// * -// DeleteObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) -// -// * -// PutObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) +// GetObjectAcl : +// - GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// - GetObjectAttributes (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) +// - DeleteObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) +// - PutObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) func (c *Client) GetObjectAcl(ctx context.Context, params *GetObjectAclInput, optFns ...func(*Options)) (*GetObjectAclOutput, error) { if params == nil { params = &GetObjectAclInput{} @@ -64,8 +58,7 @@ type GetObjectAclInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) // in the Amazon S3 User Guide. // // This member is required. @@ -82,10 +75,11 @@ type GetObjectAclInput struct { ExpectedBucketOwner *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -122,6 +116,9 @@ func (c *Client) addOperationGetObjectAclMiddlewares(stack *middleware.Stack, op if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -149,7 +146,7 @@ func (c *Client) addOperationGetObjectAclMiddlewares(stack *middleware.Stack, op if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -161,6 +158,9 @@ func (c *Client) addOperationGetObjectAclMiddlewares(stack *middleware.Stack, op if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetObjectAclResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetObjectAclValidationMiddleware(stack); err != nil { return err } @@ -170,6 +170,9 @@ func (c *Client) addOperationGetObjectAclMiddlewares(stack *middleware.Stack, op if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetObjectAclUpdateEndpoint(stack, options); err != nil { return err } @@ -185,9 +188,22 @@ func (c *Client) addOperationGetObjectAclMiddlewares(stack *middleware.Stack, op if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetObjectAclInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetObjectAcl(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -222,3 +238,139 @@ func addGetObjectAclUpdateEndpoint(stack *middleware.Stack, options Options) err DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetObjectAclResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetObjectAclResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetObjectAclResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetObjectAclInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetObjectAclResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetObjectAclResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectAttributes.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectAttributes.go index fb1683e7d..06b1ac2df 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectAttributes.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectAttributes.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "time" @@ -15,112 +21,64 @@ import ( // Retrieves all the metadata from an object without returning the object itself. // This action is useful if you're interested only in an object's metadata. To use -// GetObjectAttributes, you must have READ access to the object. -// GetObjectAttributes combines the functionality of GetObjectAcl, -// GetObjectLegalHold, GetObjectLockConfiguration, GetObjectRetention, -// GetObjectTagging, HeadObject, and ListParts. All of the data returned with each -// of those individual calls can be returned with a single call to -// GetObjectAttributes. If you encrypt an object by using server-side encryption -// with customer-provided encryption keys (SSE-C) when you store the object in -// Amazon S3, then when you retrieve the metadata from the object, you must use the -// following headers: +// GetObjectAttributes , you must have READ access to the object. +// GetObjectAttributes combines the functionality of HeadObject and ListParts . All +// of the data returned with each of those individual calls can be returned with a +// single call to GetObjectAttributes . If you encrypt an object by using +// server-side encryption with customer-provided encryption keys (SSE-C) when you +// store the object in Amazon S3, then when you retrieve the metadata from the +// object, you must use the following headers: +// - x-amz-server-side-encryption-customer-algorithm +// - x-amz-server-side-encryption-customer-key +// - x-amz-server-side-encryption-customer-key-MD5 // -// * x-amz-server-side-encryption-customer-algorithm -// -// * -// x-amz-server-side-encryption-customer-key -// -// * -// x-amz-server-side-encryption-customer-key-MD5 -// -// For more information about SSE-C, -// see Server-Side Encryption (Using Customer-Provided Encryption Keys) -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) +// For more information about SSE-C, see Server-Side Encryption (Using +// Customer-Provided Encryption Keys) (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) // in the Amazon S3 User Guide. +// - Encryption request headers, such as x-amz-server-side-encryption , should +// not be sent for GET requests if your object uses server-side encryption with +// Amazon Web Services KMS keys stored in Amazon Web Services Key Management +// Service (SSE-KMS) or server-side encryption with Amazon S3 managed keys +// (SSE-S3). If your object does use these types of keys, you'll get an HTTP 400 +// Bad Request error. +// - The last modified property in this case is the creation date of the object. // -// * Encryption request headers, such as -// x-amz-server-side-encryption, should not be sent for GET requests if your object -// uses server-side encryption with Amazon Web Services KMS keys stored in Amazon -// Web Services Key Management Service (SSE-KMS) or server-side encryption with -// Amazon S3 managed encryption keys (SSE-S3). If your object does use these types -// of keys, you'll get an HTTP 400 Bad Request error. -// -// * The last modified property -// in this case is the creation date of the object. -// -// Consider the following when -// using request headers: -// -// * If both of the If-Match and If-Unmodified-Since -// headers are present in the request as follows, then Amazon S3 returns the HTTP -// status code 200 OK and the data requested: -// -// * If-Match condition evaluates to -// true. -// -// * If-Unmodified-Since condition evaluates to false. -// -// * If both of the -// If-None-Match and If-Modified-Since headers are present in the request as -// follows, then Amazon S3 returns the HTTP status code 304 Not Modified: +// Consider the following when using request headers: +// - If both of the If-Match and If-Unmodified-Since headers are present in the +// request as follows, then Amazon S3 returns the HTTP status code 200 OK and the +// data requested: +// - If-Match condition evaluates to true . +// - If-Unmodified-Since condition evaluates to false . +// - If both of the If-None-Match and If-Modified-Since headers are present in +// the request as follows, then Amazon S3 returns the HTTP status code 304 Not +// Modified : +// - If-None-Match condition evaluates to false . +// - If-Modified-Since condition evaluates to true . // -// * -// If-None-Match condition evaluates to false. -// -// * If-Modified-Since condition -// evaluates to true. -// -// For more information about conditional requests, see RFC -// 7232 (https://tools.ietf.org/html/rfc7232). Permissions The permissions that you -// need to use this operation depend on whether the bucket is versioned. If the -// bucket is versioned, you need both the s3:GetObjectVersion and -// s3:GetObjectVersionAttributes permissions for this operation. If the bucket is -// not versioned, you need the s3:GetObject and s3:GetObjectAttributes permissions. -// For more information, see Specifying Permissions in a Policy -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html) in -// the Amazon S3 User Guide. If the object that you request does not exist, the +// For more information about conditional requests, see RFC 7232 (https://tools.ietf.org/html/rfc7232) +// . Permissions The permissions that you need to use this operation depend on +// whether the bucket is versioned. If the bucket is versioned, you need both the +// s3:GetObjectVersion and s3:GetObjectVersionAttributes permissions for this +// operation. If the bucket is not versioned, you need the s3:GetObject and +// s3:GetObjectAttributes permissions. For more information, see Specifying +// Permissions in a Policy (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html) +// in the Amazon S3 User Guide. If the object that you request does not exist, the // error Amazon S3 returns depends on whether you also have the s3:ListBucket // permission. +// - If you have the s3:ListBucket permission on the bucket, Amazon S3 returns an +// HTTP status code 404 Not Found ("no such key") error. +// - If you don't have the s3:ListBucket permission, Amazon S3 returns an HTTP +// status code 403 Forbidden ("access denied") error. // -// * If you have the s3:ListBucket permission on the bucket, Amazon S3 -// returns an HTTP status code 404 Not Found ("no such key") error. -// -// * If you don't -// have the s3:ListBucket permission, Amazon S3 returns an HTTP status code 403 -// Forbidden ("access denied") error. -// -// The following actions are related to -// GetObjectAttributes: -// -// * GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) -// -// * -// GetObjectAcl -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html) -// -// * -// GetObjectLegalHold -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectLegalHold.html) -// -// * -// GetObjectLockConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectLockConfiguration.html) -// -// * -// GetObjectRetention -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectRetention.html) -// -// * -// GetObjectTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html) -// -// * -// HeadObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html) -// -// * -// ListParts (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) +// The following actions are related to GetObjectAttributes : +// - GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// - GetObjectAcl (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html) +// - GetObjectLegalHold (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectLegalHold.html) +// - GetObjectLockConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectLockConfiguration.html) +// - GetObjectRetention (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectRetention.html) +// - GetObjectTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html) +// - HeadObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html) +// - ListParts (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) func (c *Client) GetObjectAttributes(ctx context.Context, params *GetObjectAttributesInput, optFns ...func(*Options)) (*GetObjectAttributesOutput, error) { if params == nil { params = &GetObjectAttributesInput{} @@ -144,17 +102,15 @@ type GetObjectAttributesInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -164,8 +120,8 @@ type GetObjectAttributesInput struct { // This member is required. Key *string - // An XML header that specifies the fields at the root level that you want returned - // in the response. Fields that you do not specify are not returned. + // Specifies the fields at the root level that you want returned in the response. + // Fields that you do not specify are not returned. // // This member is required. ObjectAttributes []types.ObjectAttributes @@ -178,15 +134,16 @@ type GetObjectAttributesInput struct { // Sets the maximum number of parts to return. MaxParts int32 - // Specifies the part after which listing should begin. Only parts with higher part - // numbers will be listed. + // Specifies the part after which listing should begin. Only parts with higher + // part numbers will be listed. PartNumberMarker *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -216,8 +173,8 @@ type GetObjectAttributesOutput struct { // The checksum or digest of the object. Checksum *types.Checksum - // Specifies whether the object retrieved was (true) or was not (false) a delete - // marker. If false, this response header does not appear in the response. + // Specifies whether the object retrieved was ( true ) or was not ( false ) a + // delete marker. If false , this response header does not appear in the response. DeleteMarker bool // An ETag is an opaque identifier assigned by a web server to a specific version @@ -239,8 +196,8 @@ type GetObjectAttributesOutput struct { // Provides the storage class information of the object. Amazon S3 returns this // header for all objects except for S3 Standard storage class objects. For more - // information, see Storage Classes - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html). + // information, see Storage Classes (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html) + // . StorageClass types.StorageClass // The version ID of the object. @@ -261,6 +218,9 @@ func (c *Client) addOperationGetObjectAttributesMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -288,7 +248,7 @@ func (c *Client) addOperationGetObjectAttributesMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -300,6 +260,9 @@ func (c *Client) addOperationGetObjectAttributesMiddlewares(stack *middleware.St if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetObjectAttributesResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetObjectAttributesValidationMiddleware(stack); err != nil { return err } @@ -309,6 +272,9 @@ func (c *Client) addOperationGetObjectAttributesMiddlewares(stack *middleware.St if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetObjectAttributesUpdateEndpoint(stack, options); err != nil { return err } @@ -324,9 +290,22 @@ func (c *Client) addOperationGetObjectAttributesMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetObjectAttributesInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetObjectAttributes(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -361,3 +340,139 @@ func addGetObjectAttributesUpdateEndpoint(stack *middleware.Stack, options Optio DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetObjectAttributesResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetObjectAttributesResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetObjectAttributesResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetObjectAttributesInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetObjectAttributesResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetObjectAttributesResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectLegalHold.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectLegalHold.go index a2446ac32..c43441697 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectLegalHold.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectLegalHold.go @@ -4,21 +4,25 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Gets an object's current legal hold status. For more information, see Locking -// Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html). This -// action is not supported by Amazon S3 on Outposts. The following action is -// related to GetObjectLegalHold: -// -// * GetObjectAttributes -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) +// Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html) . +// This action is not supported by Amazon S3 on Outposts. The following action is +// related to GetObjectLegalHold : +// - GetObjectAttributes (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) func (c *Client) GetObjectLegalHold(ctx context.Context, params *GetObjectLegalHoldInput, optFns ...func(*Options)) (*GetObjectLegalHoldOutput, error) { if params == nil { params = &GetObjectLegalHoldInput{} @@ -42,8 +46,7 @@ type GetObjectLegalHoldInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) // in the Amazon S3 User Guide. // // This member is required. @@ -60,10 +63,11 @@ type GetObjectLegalHoldInput struct { ExpectedBucketOwner *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -93,6 +97,9 @@ func (c *Client) addOperationGetObjectLegalHoldMiddlewares(stack *middleware.Sta if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -120,7 +127,7 @@ func (c *Client) addOperationGetObjectLegalHoldMiddlewares(stack *middleware.Sta if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -132,6 +139,9 @@ func (c *Client) addOperationGetObjectLegalHoldMiddlewares(stack *middleware.Sta if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetObjectLegalHoldResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetObjectLegalHoldValidationMiddleware(stack); err != nil { return err } @@ -141,6 +151,9 @@ func (c *Client) addOperationGetObjectLegalHoldMiddlewares(stack *middleware.Sta if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetObjectLegalHoldUpdateEndpoint(stack, options); err != nil { return err } @@ -156,9 +169,22 @@ func (c *Client) addOperationGetObjectLegalHoldMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetObjectLegalHoldInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetObjectLegalHold(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -193,3 +219,139 @@ func addGetObjectLegalHoldUpdateEndpoint(stack *middleware.Stack, options Option DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetObjectLegalHoldResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetObjectLegalHoldResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetObjectLegalHoldResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetObjectLegalHoldInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetObjectLegalHoldResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetObjectLegalHoldResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectLockConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectLockConfiguration.go index 91793c133..eb142dada 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectLockConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectLockConfiguration.go @@ -4,23 +4,25 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Gets the Object Lock configuration for a bucket. The rule specified in the // Object Lock configuration will be applied by default to every new object placed -// in the specified bucket. For more information, see Locking Objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html). The -// following action is related to GetObjectLockConfiguration: -// -// * -// GetObjectAttributes -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) +// in the specified bucket. For more information, see Locking Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html) +// . The following action is related to GetObjectLockConfiguration : +// - GetObjectAttributes (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) func (c *Client) GetObjectLockConfiguration(ctx context.Context, params *GetObjectLockConfigurationInput, optFns ...func(*Options)) (*GetObjectLockConfigurationOutput, error) { if params == nil { params = &GetObjectLockConfigurationInput{} @@ -38,14 +40,13 @@ func (c *Client) GetObjectLockConfiguration(ctx context.Context, params *GetObje type GetObjectLockConfigurationInput struct { - // The bucket whose Object Lock configuration you want to retrieve. When using this - // action with an access point, you must direct requests to the access point + // The bucket whose Object Lock configuration you want to retrieve. When using + // this action with an access point, you must direct requests to the access point // hostname. The access point hostname takes the form // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) // in the Amazon S3 User Guide. // // This member is required. @@ -79,6 +80,9 @@ func (c *Client) addOperationGetObjectLockConfigurationMiddlewares(stack *middle if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -106,7 +110,7 @@ func (c *Client) addOperationGetObjectLockConfigurationMiddlewares(stack *middle if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -118,6 +122,9 @@ func (c *Client) addOperationGetObjectLockConfigurationMiddlewares(stack *middle if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetObjectLockConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetObjectLockConfigurationValidationMiddleware(stack); err != nil { return err } @@ -127,6 +134,9 @@ func (c *Client) addOperationGetObjectLockConfigurationMiddlewares(stack *middle if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetObjectLockConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -142,9 +152,22 @@ func (c *Client) addOperationGetObjectLockConfigurationMiddlewares(stack *middle if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetObjectLockConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetObjectLockConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -154,9 +177,9 @@ func newServiceMetadataMiddleware_opGetObjectLockConfiguration(region string) *a } } -// getGetObjectLockConfigurationBucketMember returns a pointer to string denoting a -// provided bucket member valueand a boolean indicating if the input has a modeled -// bucket name, +// getGetObjectLockConfigurationBucketMember returns a pointer to string denoting +// a provided bucket member valueand a boolean indicating if the input has a +// modeled bucket name, func getGetObjectLockConfigurationBucketMember(input interface{}) (*string, bool) { in := input.(*GetObjectLockConfigurationInput) if in.Bucket == nil { @@ -179,3 +202,139 @@ func addGetObjectLockConfigurationUpdateEndpoint(stack *middleware.Stack, option DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetObjectLockConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetObjectLockConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetObjectLockConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetObjectLockConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetObjectLockConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetObjectLockConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectRetention.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectRetention.go index 33fc04897..278d13522 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectRetention.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectRetention.go @@ -4,21 +4,25 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Retrieves an object's retention settings. For more information, see Locking -// Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html). This -// action is not supported by Amazon S3 on Outposts. The following action is -// related to GetObjectRetention: -// -// * GetObjectAttributes -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) +// Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html) . +// This action is not supported by Amazon S3 on Outposts. The following action is +// related to GetObjectRetention : +// - GetObjectAttributes (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) func (c *Client) GetObjectRetention(ctx context.Context, params *GetObjectRetentionInput, optFns ...func(*Options)) (*GetObjectRetentionOutput, error) { if params == nil { params = &GetObjectRetentionInput{} @@ -42,8 +46,7 @@ type GetObjectRetentionInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) // in the Amazon S3 User Guide. // // This member is required. @@ -60,10 +63,11 @@ type GetObjectRetentionInput struct { ExpectedBucketOwner *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -93,6 +97,9 @@ func (c *Client) addOperationGetObjectRetentionMiddlewares(stack *middleware.Sta if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -120,7 +127,7 @@ func (c *Client) addOperationGetObjectRetentionMiddlewares(stack *middleware.Sta if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -132,6 +139,9 @@ func (c *Client) addOperationGetObjectRetentionMiddlewares(stack *middleware.Sta if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetObjectRetentionResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetObjectRetentionValidationMiddleware(stack); err != nil { return err } @@ -141,6 +151,9 @@ func (c *Client) addOperationGetObjectRetentionMiddlewares(stack *middleware.Sta if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetObjectRetentionUpdateEndpoint(stack, options); err != nil { return err } @@ -156,9 +169,22 @@ func (c *Client) addOperationGetObjectRetentionMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetObjectRetentionInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetObjectRetention(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -193,3 +219,139 @@ func addGetObjectRetentionUpdateEndpoint(stack *middleware.Stack, options Option DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetObjectRetentionResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetObjectRetentionResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetObjectRetentionResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetObjectRetentionInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetObjectRetentionResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetObjectRetentionResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectTagging.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectTagging.go index cec5210c2..14ebf1c4e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectTagging.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectTagging.go @@ -4,36 +4,33 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns the tag-set of an object. You send the GET request against the tagging // subresource associated with the object. To use this operation, you must have -// permission to perform the s3:GetObjectTagging action. By default, the GET action -// returns information about current version of an object. For a versioned bucket, -// you can have multiple versions of an object in your bucket. To retrieve tags of -// any other version, use the versionId query parameter. You also need permission -// for the s3:GetObjectVersionTagging action. By default, the bucket owner has this -// permission and can grant this permission to others. For information about the -// Amazon S3 object tagging feature, see Object Tagging -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html). The -// following actions are related to GetObjectTagging: -// -// * DeleteObjectTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html) -// -// * -// GetObjectAttributes -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) -// -// * -// PutObjectTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html) +// permission to perform the s3:GetObjectTagging action. By default, the GET +// action returns information about current version of an object. For a versioned +// bucket, you can have multiple versions of an object in your bucket. To retrieve +// tags of any other version, use the versionId query parameter. You also need +// permission for the s3:GetObjectVersionTagging action. By default, the bucket +// owner has this permission and can grant this permission to others. For +// information about the Amazon S3 object tagging feature, see Object Tagging (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html) +// . The following actions are related to GetObjectTagging : +// - DeleteObjectTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html) +// - GetObjectAttributes (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) +// - PutObjectTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html) func (c *Client) GetObjectTagging(ctx context.Context, params *GetObjectTaggingInput, optFns ...func(*Options)) (*GetObjectTaggingOutput, error) { if params == nil { params = &GetObjectTaggingInput{} @@ -57,17 +54,15 @@ type GetObjectTaggingInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -83,10 +78,11 @@ type GetObjectTaggingInput struct { ExpectedBucketOwner *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -121,6 +117,9 @@ func (c *Client) addOperationGetObjectTaggingMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -148,7 +147,7 @@ func (c *Client) addOperationGetObjectTaggingMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -160,6 +159,9 @@ func (c *Client) addOperationGetObjectTaggingMiddlewares(stack *middleware.Stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetObjectTaggingResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetObjectTaggingValidationMiddleware(stack); err != nil { return err } @@ -169,6 +171,9 @@ func (c *Client) addOperationGetObjectTaggingMiddlewares(stack *middleware.Stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetObjectTaggingUpdateEndpoint(stack, options); err != nil { return err } @@ -184,9 +189,22 @@ func (c *Client) addOperationGetObjectTaggingMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetObjectTaggingInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetObjectTagging(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -221,3 +239,139 @@ func addGetObjectTaggingUpdateEndpoint(stack *middleware.Stack, options Options) DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetObjectTaggingResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetObjectTaggingResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetObjectTaggingResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetObjectTaggingInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetObjectTaggingResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetObjectTaggingResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectTorrent.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectTorrent.go index fa71442c2..dd06c1bde 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectTorrent.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetObjectTorrent.go @@ -4,27 +4,28 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "io" ) // Returns torrent files from a bucket. BitTorrent can save you bandwidth when -// you're distributing large files. For more information about BitTorrent, see -// Using BitTorrent with Amazon S3 -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/S3Torrent.html). You can get -// torrent only for objects that are less than 5 GB in size, and that are not -// encrypted using server-side encryption with a customer-provided encryption key. -// To use GET, you must have READ access to the object. This action is not -// supported by Amazon S3 on Outposts. The following action is related to -// GetObjectTorrent: -// -// * GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// you're distributing large files. You can get torrent only for objects that are +// less than 5 GB in size, and that are not encrypted using server-side encryption +// with a customer-provided encryption key. To use GET, you must have READ access +// to the object. This action is not supported by Amazon S3 on Outposts. The +// following action is related to GetObjectTorrent : +// - GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) func (c *Client) GetObjectTorrent(ctx context.Context, params *GetObjectTorrentInput, optFns ...func(*Options)) (*GetObjectTorrentOutput, error) { if params == nil { params = &GetObjectTorrentInput{} @@ -58,10 +59,11 @@ type GetObjectTorrentInput struct { ExpectedBucketOwner *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -92,6 +94,9 @@ func (c *Client) addOperationGetObjectTorrentMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -119,7 +124,7 @@ func (c *Client) addOperationGetObjectTorrentMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -128,6 +133,9 @@ func (c *Client) addOperationGetObjectTorrentMiddlewares(stack *middleware.Stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetObjectTorrentResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetObjectTorrentValidationMiddleware(stack); err != nil { return err } @@ -137,6 +145,9 @@ func (c *Client) addOperationGetObjectTorrentMiddlewares(stack *middleware.Stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetObjectTorrentUpdateEndpoint(stack, options); err != nil { return err } @@ -152,9 +163,22 @@ func (c *Client) addOperationGetObjectTorrentMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetObjectTorrentInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetObjectTorrent(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -189,3 +213,139 @@ func addGetObjectTorrentUpdateEndpoint(stack *middleware.Stack, options Options) DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetObjectTorrentResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetObjectTorrentResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetObjectTorrentResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetObjectTorrentInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetObjectTorrentResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetObjectTorrentResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetPublicAccessBlock.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetPublicAccessBlock.go index eb42c7d27..cd09834c0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetPublicAccessBlock.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_GetPublicAccessBlock.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -15,33 +21,19 @@ import ( // Retrieves the PublicAccessBlock configuration for an Amazon S3 bucket. To use // this operation, you must have the s3:GetBucketPublicAccessBlock permission. For // more information about Amazon S3 permissions, see Specifying Permissions in a -// Policy -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html). -// When Amazon S3 evaluates the PublicAccessBlock configuration for a bucket or an -// object, it checks the PublicAccessBlock configuration for both the bucket (or -// the bucket that contains the object) and the bucket owner's account. If the +// Policy (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html) +// . When Amazon S3 evaluates the PublicAccessBlock configuration for a bucket or +// an object, it checks the PublicAccessBlock configuration for both the bucket +// (or the bucket that contains the object) and the bucket owner's account. If the // PublicAccessBlock settings are different between the bucket and the account, // Amazon S3 uses the most restrictive combination of the bucket-level and // account-level settings. For more information about when Amazon S3 considers a -// bucket or an object public, see The Meaning of "Public" -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html#access-control-block-public-access-policy-status). -// The following operations are related to GetPublicAccessBlock: -// -// * Using Amazon S3 -// Block Public Access -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html) -// -// * -// PutPublicAccessBlock -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutPublicAccessBlock.html) -// -// * -// GetPublicAccessBlock -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetPublicAccessBlock.html) -// -// * -// DeletePublicAccessBlock -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeletePublicAccessBlock.html) +// bucket or an object public, see The Meaning of "Public" (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html#access-control-block-public-access-policy-status) +// . The following operations are related to GetPublicAccessBlock : +// - Using Amazon S3 Block Public Access (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html) +// - PutPublicAccessBlock (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutPublicAccessBlock.html) +// - GetPublicAccessBlock (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetPublicAccessBlock.html) +// - DeletePublicAccessBlock (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeletePublicAccessBlock.html) func (c *Client) GetPublicAccessBlock(ctx context.Context, params *GetPublicAccessBlockInput, optFns ...func(*Options)) (*GetPublicAccessBlockOutput, error) { if params == nil { params = &GetPublicAccessBlockInput{} @@ -94,6 +86,9 @@ func (c *Client) addOperationGetPublicAccessBlockMiddlewares(stack *middleware.S if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -121,7 +116,7 @@ func (c *Client) addOperationGetPublicAccessBlockMiddlewares(stack *middleware.S if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -133,6 +128,9 @@ func (c *Client) addOperationGetPublicAccessBlockMiddlewares(stack *middleware.S if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addGetPublicAccessBlockResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetPublicAccessBlockValidationMiddleware(stack); err != nil { return err } @@ -142,6 +140,9 @@ func (c *Client) addOperationGetPublicAccessBlockMiddlewares(stack *middleware.S if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addGetPublicAccessBlockUpdateEndpoint(stack, options); err != nil { return err } @@ -157,9 +158,22 @@ func (c *Client) addOperationGetPublicAccessBlockMiddlewares(stack *middleware.S if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *GetPublicAccessBlockInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opGetPublicAccessBlock(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -194,3 +208,139 @@ func addGetPublicAccessBlockUpdateEndpoint(stack *middleware.Stack, options Opti DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opGetPublicAccessBlockResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetPublicAccessBlockResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetPublicAccessBlockResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*GetPublicAccessBlockInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetPublicAccessBlockResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetPublicAccessBlockResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_HeadBucket.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_HeadBucket.go index c3d9a16f2..a65218224 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_HeadBucket.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_HeadBucket.go @@ -6,10 +6,14 @@ import ( "context" "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithytime "github.com/aws/smithy-go/time" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -17,27 +21,30 @@ import ( "time" ) -// This action is useful to determine if a bucket exists and you have permission to -// access it. The action returns a 200 OK if the bucket exists and you have +// This action is useful to determine if a bucket exists and you have permission +// to access it. The action returns a 200 OK if the bucket exists and you have // permission to access it. If the bucket does not exist or you do not have -// permission to access it, the HEAD request returns a generic 404 Not Found or 403 -// Forbidden code. A message body is not included, so you cannot determine the -// exception beyond these error codes. To use this operation, you must have -// permissions to perform the s3:ListBucket action. The bucket owner has this -// permission by default and can grant this permission to others. For more +// permission to access it, the HEAD request returns a generic 400 Bad Request , +// 403 Forbidden or 404 Not Found code. A message body is not included, so you +// cannot determine the exception beyond these error codes. To use this operation, +// you must have permissions to perform the s3:ListBucket action. The bucket owner +// has this permission by default and can grant this permission to others. For more // information about permissions, see Permissions Related to Bucket Subresource -// Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// To use this API against an access point, you must provide the alias of the -// access point in place of the bucket name or specify the access point ARN. When -// using the access point ARN, you must direct requests to the access point +// Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . To use this API operation against an access point, you must provide the alias +// of the access point in place of the bucket name or specify the access point ARN. +// When using the access point ARN, you must direct requests to the access point // hostname. The access point hostname takes the form // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using the // Amazon Web Services SDKs, you provide the ARN in place of the bucket name. For -// more information see, Using access points -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html). +// more information, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) +// . To use this API operation against an Object Lambda access point, provide the +// alias of the Object Lambda access point in place of the bucket name. If the +// Object Lambda access point alias in a request is not valid, the error code +// InvalidAccessPointAliasError is returned. For more information about +// InvalidAccessPointAliasError , see List of Error Codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) +// . func (c *Client) HeadBucket(ctx context.Context, params *HeadBucketInput, optFns ...func(*Options)) (*HeadBucketOutput, error) { if params == nil { params = &HeadBucketInput{} @@ -60,17 +67,19 @@ type HeadBucketInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with an Object Lambda + // access point, provide the alias of the Object Lambda access point in place of + // the bucket name. If the Object Lambda access point alias in a request is not + // valid, the error code InvalidAccessPointAliasError is returned. For more + // information about InvalidAccessPointAliasError , see List of Error Codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) + // . When you use this action with Amazon S3 on Outposts, you must direct requests + // to the S3 on Outposts hostname. The S3 on Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -99,6 +108,9 @@ func (c *Client) addOperationHeadBucketMiddlewares(stack *middleware.Stack, opti if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -126,7 +138,7 @@ func (c *Client) addOperationHeadBucketMiddlewares(stack *middleware.Stack, opti if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -138,6 +150,9 @@ func (c *Client) addOperationHeadBucketMiddlewares(stack *middleware.Stack, opti if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addHeadBucketResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpHeadBucketValidationMiddleware(stack); err != nil { return err } @@ -147,6 +162,9 @@ func (c *Client) addOperationHeadBucketMiddlewares(stack *middleware.Stack, opti if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addHeadBucketUpdateEndpoint(stack, options); err != nil { return err } @@ -162,9 +180,22 @@ func (c *Client) addOperationHeadBucketMiddlewares(stack *middleware.Stack, opti if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *HeadBucketInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + // HeadBucketAPIClient is a client that implements the HeadBucket operation. type HeadBucketAPIClient interface { HeadBucket(context.Context, *HeadBucketInput, ...func(*Options)) (*HeadBucketOutput, error) @@ -185,9 +216,9 @@ type BucketExistsWaiterOptions struct { // MinDelay must resolve to a value lesser than or equal to the MaxDelay. MinDelay time.Duration - // MaxDelay is the maximum amount of time to delay between retries. If unset or set - // to zero, BucketExistsWaiter will use default max delay of 120 seconds. Note that - // MaxDelay must resolve to value greater than or equal to the MinDelay. + // MaxDelay is the maximum amount of time to delay between retries. If unset or + // set to zero, BucketExistsWaiter will use default max delay of 120 seconds. Note + // that MaxDelay must resolve to value greater than or equal to the MinDelay. MaxDelay time.Duration // LogWaitAttempts is used to enable logging for waiter retry attempts @@ -338,9 +369,9 @@ type BucketNotExistsWaiterOptions struct { // MinDelay must resolve to a value lesser than or equal to the MaxDelay. MinDelay time.Duration - // MaxDelay is the maximum amount of time to delay between retries. If unset or set - // to zero, BucketNotExistsWaiter will use default max delay of 120 seconds. Note - // that MaxDelay must resolve to value greater than or equal to the MinDelay. + // MaxDelay is the maximum amount of time to delay between retries. If unset or + // set to zero, BucketNotExistsWaiter will use default max delay of 120 seconds. + // Note that MaxDelay must resolve to value greater than or equal to the MinDelay. MaxDelay time.Duration // LogWaitAttempts is used to enable logging for waiter retry attempts @@ -380,9 +411,9 @@ func NewBucketNotExistsWaiter(client HeadBucketAPIClient, optFns ...func(*Bucket } } -// Wait calls the waiter function for BucketNotExists waiter. The maxWaitDur is the -// maximum wait duration the waiter will wait. The maxWaitDur is required and must -// be greater than zero. +// Wait calls the waiter function for BucketNotExists waiter. The maxWaitDur is +// the maximum wait duration the waiter will wait. The maxWaitDur is required and +// must be greater than zero. func (w *BucketNotExistsWaiter) Wait(ctx context.Context, params *HeadBucketInput, maxWaitDur time.Duration, optFns ...func(*BucketNotExistsWaiterOptions)) error { _, err := w.WaitForOutput(ctx, params, maxWaitDur, optFns...) return err @@ -484,8 +515,9 @@ func newServiceMetadataMiddleware_opHeadBucket(region string) *awsmiddleware.Reg } } -// getHeadBucketBucketMember returns a pointer to string denoting a provided bucket -// member valueand a boolean indicating if the input has a modeled bucket name, +// getHeadBucketBucketMember returns a pointer to string denoting a provided +// bucket member valueand a boolean indicating if the input has a modeled bucket +// name, func getHeadBucketBucketMember(input interface{}) (*string, bool) { in := input.(*HeadBucketInput) if in.Bucket == nil { @@ -539,3 +571,139 @@ func addHeadBucketPayloadAsUnsigned(stack *middleware.Stack, options Options) er v4.RemoveComputePayloadSHA256Middleware(stack) return v4.AddUnsignedPayloadMiddleware(stack) } + +type opHeadBucketResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opHeadBucketResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opHeadBucketResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*HeadBucketInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addHeadBucketResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opHeadBucketResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_HeadObject.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_HeadObject.go index 1e745a7e5..a121acb16 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_HeadObject.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_HeadObject.go @@ -6,11 +6,14 @@ import ( "context" "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" - smithy "github.com/aws/smithy-go" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithytime "github.com/aws/smithy-go/time" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -20,91 +23,58 @@ import ( // The HEAD action retrieves metadata from an object without returning the object // itself. This action is useful if you're only interested in an object's metadata. -// To use HEAD, you must have READ access to the object. A HEAD request has the +// To use HEAD , you must have READ access to the object. A HEAD request has the // same options as a GET action on an object. The response is identical to the GET // response except that there is no response body. Because of this, if the HEAD -// request generates an error, it returns a generic 404 Not Found or 403 Forbidden -// code. It is not possible to retrieve the exact exception beyond these error -// codes. If you encrypt an object by using server-side encryption with -// customer-provided encryption keys (SSE-C) when you store the object in Amazon -// S3, then when you retrieve the metadata from the object, you must use the -// following headers: +// request generates an error, it returns a generic 400 Bad Request , 403 Forbidden +// or 404 Not Found code. It is not possible to retrieve the exact exception +// beyond these error codes. If you encrypt an object by using server-side +// encryption with customer-provided encryption keys (SSE-C) when you store the +// object in Amazon S3, then when you retrieve the metadata from the object, you +// must use the following headers: +// - x-amz-server-side-encryption-customer-algorithm +// - x-amz-server-side-encryption-customer-key +// - x-amz-server-side-encryption-customer-key-MD5 // -// * x-amz-server-side-encryption-customer-algorithm +// For more information about SSE-C, see Server-Side Encryption (Using +// Customer-Provided Encryption Keys) (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) +// . +// - Encryption request headers, like x-amz-server-side-encryption , should not +// be sent for GET requests if your object uses server-side encryption with Key +// Management Service (KMS) keys (SSE-KMS), dual-layer server-side encryption with +// Amazon Web Services KMS keys (DSSE-KMS), or server-side encryption with Amazon +// S3 managed encryption keys (SSE-S3). If your object does use these types of +// keys, you’ll get an HTTP 400 Bad Request error. +// - The last modified property in this case is the creation date of the object. // -// * -// x-amz-server-side-encryption-customer-key +// Request headers are limited to 8 KB in size. For more information, see Common +// Request Headers (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonRequestHeaders.html) +// . Consider the following when using request headers: +// - Consideration 1 – If both of the If-Match and If-Unmodified-Since headers +// are present in the request as follows: +// - If-Match condition evaluates to true , and; +// - If-Unmodified-Since condition evaluates to false ; Then Amazon S3 returns +// 200 OK and the data requested. +// - Consideration 2 – If both of the If-None-Match and If-Modified-Since headers +// are present in the request as follows: +// - If-None-Match condition evaluates to false , and; +// - If-Modified-Since condition evaluates to true ; Then Amazon S3 returns the +// 304 Not Modified response code. // -// * -// x-amz-server-side-encryption-customer-key-MD5 +// For more information about conditional requests, see RFC 7232 (https://tools.ietf.org/html/rfc7232) +// . Permissions You need the relevant read object (or version) permission for this +// operation. For more information, see Actions, resources, and condition keys for +// Amazon S3 (https://docs.aws.amazon.com/AmazonS3/latest/dev/list_amazons3.html) . +// If the object you request doesn't exist, the error that Amazon S3 returns +// depends on whether you also have the s3:ListBucket permission. +// - If you have the s3:ListBucket permission on the bucket, Amazon S3 returns an +// HTTP status code 404 error. +// - If you don’t have the s3:ListBucket permission, Amazon S3 returns an HTTP +// status code 403 error. // -// For more information about SSE-C, -// see Server-Side Encryption (Using Customer-Provided Encryption Keys) -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html). -// -// * -// Encryption request headers, like x-amz-server-side-encryption, should not be -// sent for GET requests if your object uses server-side encryption with KMS keys -// (SSE-KMS) or server-side encryption with Amazon S3–managed encryption keys -// (SSE-S3). If your object does use these types of keys, you’ll get an HTTP 400 -// BadRequest error. -// -// * The last modified property in this case is the creation -// date of the object. -// -// Request headers are limited to 8 KB in size. For more -// information, see Common Request Headers -// (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonRequestHeaders.html). -// Consider the following when using request headers: -// -// * Consideration 1 – If both -// of the If-Match and If-Unmodified-Since headers are present in the request as -// follows: -// -// * If-Match condition evaluates to true, and; -// -// * If-Unmodified-Since -// condition evaluates to false; -// -// Then Amazon S3 returns 200 OK and the data -// requested. -// -// * Consideration 2 – If both of the If-None-Match and -// If-Modified-Since headers are present in the request as follows: -// -// * -// If-None-Match condition evaluates to false, and; -// -// * If-Modified-Since condition -// evaluates to true; -// -// Then Amazon S3 returns the 304 Not Modified response -// code. -// -// For more information about conditional requests, see RFC 7232 -// (https://tools.ietf.org/html/rfc7232). Permissions You need the relevant read -// object (or version) permission for this operation. For more information, see -// Specifying Permissions in a Policy -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html). If -// the object you request does not exist, the error Amazon S3 returns depends on -// whether you also have the s3:ListBucket permission. -// -// * If you have the -// s3:ListBucket permission on the bucket, Amazon S3 returns an HTTP status code -// 404 ("no such key") error. -// -// * If you don’t have the s3:ListBucket permission, -// Amazon S3 returns an HTTP status code 403 ("access denied") error. -// -// The -// following actions are related to HeadObject: -// -// * GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) -// -// * -// GetObjectAttributes -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) +// The following actions are related to HeadObject : +// - GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// - GetObjectAttributes (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) func (c *Client) HeadObject(ctx context.Context, params *HeadObjectInput, optFns ...func(*Options)) (*HeadObjectOutput, error) { if params == nil { params = &HeadObjectInput{} @@ -128,17 +98,15 @@ type HeadObjectInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -181,15 +149,17 @@ type HeadObjectInput struct { // object. PartNumber int32 - // Because HeadObject returns only the metadata for an object, this parameter has - // no effect. + // HeadObject returns only the metadata for an object. If the Range is + // satisfiable, only the ContentLength is affected in the response. If the Range + // is not satisfiable, S3 returns a 416 - Requested Range Not Satisfiable error. Range *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -224,7 +194,7 @@ type HeadObjectOutput struct { ArchiveStatus types.ArchiveStatus // Indicates whether the object uses an S3 Bucket Key for server-side encryption - // with Amazon Web Services KMS (SSE-KMS). + // with Key Management Service (KMS) keys (SSE-KMS). BucketKeyEnabled bool // Specifies caching behavior along the request/reply chain. @@ -233,32 +203,28 @@ type HeadObjectOutput struct { // The base64-encoded, 32-bit CRC32 checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32 *string // The base64-encoded, 32-bit CRC32C checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32C *string // The base64-encoded, 160-bit SHA-1 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA1 *string // The base64-encoded, 256-bit SHA-256 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA256 *string @@ -310,17 +276,17 @@ type HeadObjectOutput struct { // can create metadata whose values are not legal HTTP headers. MissingMeta int32 - // Specifies whether a legal hold is in effect for this object. This header is only - // returned if the requester has the s3:GetObjectLegalHold permission. This header - // is not returned if the specified version of this object has never had a legal - // hold applied. For more information about S3 Object Lock, see Object Lock - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html). + // Specifies whether a legal hold is in effect for this object. This header is + // only returned if the requester has the s3:GetObjectLegalHold permission. This + // header is not returned if the specified version of this object has never had a + // legal hold applied. For more information about S3 Object Lock, see Object Lock (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html) + // . ObjectLockLegalHoldStatus types.ObjectLockLegalHoldStatus // The Object Lock mode, if any, that's in effect for this object. This header is // only returned if the requester has the s3:GetObjectRetention permission. For - // more information about S3 Object Lock, see Object Lock - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html). + // more information about S3 Object Lock, see Object Lock (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html) + // . ObjectLockMode types.ObjectLockMode // The date and time when the Object Lock retention period expires. This header is @@ -334,36 +300,30 @@ type HeadObjectOutput struct { // Amazon S3 can return this header if your request involves a bucket that is // either a source or a destination in a replication rule. In replication, you have // a source bucket on which you configure replication and destination bucket or - // buckets where Amazon S3 stores object replicas. When you request an object - // (GetObject) or object metadata (HeadObject) from these buckets, Amazon S3 will + // buckets where Amazon S3 stores object replicas. When you request an object ( + // GetObject ) or object metadata ( HeadObject ) from these buckets, Amazon S3 will // return the x-amz-replication-status header in the response as follows: - // - // * If - // requesting an object from the source bucket, Amazon S3 will return the - // x-amz-replication-status header if the object in your request is eligible for - // replication. For example, suppose that in your replication configuration, you - // specify object prefix TaxDocs requesting Amazon S3 to replicate objects with key - // prefix TaxDocs. Any objects you upload with this key name prefix, for example - // TaxDocs/document1.pdf, are eligible for replication. For any object request with - // this key name prefix, Amazon S3 will return the x-amz-replication-status header - // with value PENDING, COMPLETED or FAILED indicating object replication status. - // - // * - // If requesting an object from a destination bucket, Amazon S3 will return the - // x-amz-replication-status header with value REPLICA if the object in your request - // is a replica that Amazon S3 created and there is no replica modification - // replication in progress. - // - // * When replicating objects to multiple destination - // buckets, the x-amz-replication-status header acts differently. The header of the - // source object will only return a value of COMPLETED when replication is - // successful to all destinations. The header will remain at value PENDING until - // replication has completed for all destinations. If one or more destinations - // fails replication the header will return FAILED. - // - // For more information, see - // Replication - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html). + // - If requesting an object from the source bucket, Amazon S3 will return the + // x-amz-replication-status header if the object in your request is eligible for + // replication. For example, suppose that in your replication configuration, you + // specify object prefix TaxDocs requesting Amazon S3 to replicate objects with + // key prefix TaxDocs . Any objects you upload with this key name prefix, for + // example TaxDocs/document1.pdf , are eligible for replication. For any object + // request with this key name prefix, Amazon S3 will return the + // x-amz-replication-status header with value PENDING, COMPLETED or FAILED + // indicating object replication status. + // - If requesting an object from a destination bucket, Amazon S3 will return + // the x-amz-replication-status header with value REPLICA if the object in your + // request is a replica that Amazon S3 created and there is no replica modification + // replication in progress. + // - When replicating objects to multiple destination buckets, the + // x-amz-replication-status header acts differently. The header of the source + // object will only return a value of COMPLETED when replication is successful to + // all destinations. The header will remain at value PENDING until replication has + // completed for all destinations. If one or more destinations fails replication + // the header will return FAILED. + // For more information, see Replication (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) + // . ReplicationStatus types.ReplicationStatus // If present, indicates that the requester was successfully charged for the @@ -372,41 +332,38 @@ type HeadObjectOutput struct { // If the object is an archived object (an object whose storage class is GLACIER), // the response includes this header if either the archive restoration is in - // progress (see RestoreObject - // (https://docs.aws.amazon.com/AmazonS3/latest/API/API_RestoreObject.html) or an - // archive copy is already restored. If an archive copy is already restored, the - // header value indicates when Amazon S3 is scheduled to delete the object copy. - // For example: x-amz-restore: ongoing-request="false", expiry-date="Fri, 21 Dec - // 2012 00:00:00 GMT" If the object restoration is in progress, the header returns - // the value ongoing-request="true". For more information about archiving objects, - // see Transitioning Objects: General Considerations - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html#lifecycle-transition-general-considerations). + // progress (see RestoreObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_RestoreObject.html) + // or an archive copy is already restored. If an archive copy is already restored, + // the header value indicates when Amazon S3 is scheduled to delete the object + // copy. For example: x-amz-restore: ongoing-request="false", expiry-date="Fri, 21 + // Dec 2012 00:00:00 GMT" If the object restoration is in progress, the header + // returns the value ongoing-request="true" . For more information about archiving + // objects, see Transitioning Objects: General Considerations (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html#lifecycle-transition-general-considerations) + // . Restore *string - // If server-side encryption with a customer-provided encryption key was requested, - // the response will include this header confirming the encryption algorithm used. + // If server-side encryption with a customer-provided encryption key was + // requested, the response will include this header confirming the encryption + // algorithm used. SSECustomerAlgorithm *string - // If server-side encryption with a customer-provided encryption key was requested, - // the response will include this header to provide round-trip message integrity - // verification of the customer-provided encryption key. + // If server-side encryption with a customer-provided encryption key was + // requested, the response will include this header to provide round-trip message + // integrity verification of the customer-provided encryption key. SSECustomerKeyMD5 *string - // If present, specifies the ID of the Amazon Web Services Key Management Service - // (Amazon Web Services KMS) symmetric customer managed key that was used for the - // object. + // If present, specifies the ID of the Key Management Service (KMS) symmetric + // encryption customer managed key that was used for the object. SSEKMSKeyId *string - // If the object is stored using server-side encryption either with an Amazon Web - // Services KMS key or an Amazon S3-managed encryption key, the response includes - // this header with the value of the server-side encryption algorithm used when - // storing this object in Amazon S3 (for example, AES256, aws:kms). + // The server-side encryption algorithm used when storing this object in Amazon S3 + // (for example, AES256 , aws:kms , aws:kms:dsse ). ServerSideEncryption types.ServerSideEncryption // Provides storage class information of the object. Amazon S3 returns this header // for all objects except for S3 Standard storage class objects. For more - // information, see Storage Classes - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html). + // information, see Storage Classes (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html) + // . StorageClass types.StorageClass // Version of the object. @@ -432,6 +389,9 @@ func (c *Client) addOperationHeadObjectMiddlewares(stack *middleware.Stack, opti if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -459,7 +419,7 @@ func (c *Client) addOperationHeadObjectMiddlewares(stack *middleware.Stack, opti if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -471,6 +431,9 @@ func (c *Client) addOperationHeadObjectMiddlewares(stack *middleware.Stack, opti if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addHeadObjectResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpHeadObjectValidationMiddleware(stack); err != nil { return err } @@ -480,6 +443,9 @@ func (c *Client) addOperationHeadObjectMiddlewares(stack *middleware.Stack, opti if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addHeadObjectUpdateEndpoint(stack, options); err != nil { return err } @@ -495,9 +461,22 @@ func (c *Client) addOperationHeadObjectMiddlewares(stack *middleware.Stack, opti if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *HeadObjectInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + // HeadObjectAPIClient is a client that implements the HeadObject operation. type HeadObjectAPIClient interface { HeadObject(context.Context, *HeadObjectInput, ...func(*Options)) (*HeadObjectOutput, error) @@ -518,9 +497,9 @@ type ObjectExistsWaiterOptions struct { // MinDelay must resolve to a value lesser than or equal to the MaxDelay. MinDelay time.Duration - // MaxDelay is the maximum amount of time to delay between retries. If unset or set - // to zero, ObjectExistsWaiter will use default max delay of 120 seconds. Note that - // MaxDelay must resolve to value greater than or equal to the MinDelay. + // MaxDelay is the maximum amount of time to delay between retries. If unset or + // set to zero, ObjectExistsWaiter will use default max delay of 120 seconds. Note + // that MaxDelay must resolve to value greater than or equal to the MinDelay. MaxDelay time.Duration // LogWaitAttempts is used to enable logging for waiter retry attempts @@ -649,13 +628,8 @@ func objectExistsStateRetryable(ctx context.Context, input *HeadObjectInput, out } if err != nil { - var apiErr smithy.APIError - ok := errors.As(err, &apiErr) - if !ok { - return false, fmt.Errorf("expected err to be of type smithy.APIError, got %w", err) - } - - if "NotFound" == apiErr.ErrorCode() { + var errorType *types.NotFound + if errors.As(err, &errorType) { return true, nil } } @@ -676,9 +650,9 @@ type ObjectNotExistsWaiterOptions struct { // MinDelay must resolve to a value lesser than or equal to the MaxDelay. MinDelay time.Duration - // MaxDelay is the maximum amount of time to delay between retries. If unset or set - // to zero, ObjectNotExistsWaiter will use default max delay of 120 seconds. Note - // that MaxDelay must resolve to value greater than or equal to the MinDelay. + // MaxDelay is the maximum amount of time to delay between retries. If unset or + // set to zero, ObjectNotExistsWaiter will use default max delay of 120 seconds. + // Note that MaxDelay must resolve to value greater than or equal to the MinDelay. MaxDelay time.Duration // LogWaitAttempts is used to enable logging for waiter retry attempts @@ -718,9 +692,9 @@ func NewObjectNotExistsWaiter(client HeadObjectAPIClient, optFns ...func(*Object } } -// Wait calls the waiter function for ObjectNotExists waiter. The maxWaitDur is the -// maximum wait duration the waiter will wait. The maxWaitDur is required and must -// be greater than zero. +// Wait calls the waiter function for ObjectNotExists waiter. The maxWaitDur is +// the maximum wait duration the waiter will wait. The maxWaitDur is required and +// must be greater than zero. func (w *ObjectNotExistsWaiter) Wait(ctx context.Context, params *HeadObjectInput, maxWaitDur time.Duration, optFns ...func(*ObjectNotExistsWaiterOptions)) error { _, err := w.WaitForOutput(ctx, params, maxWaitDur, optFns...) return err @@ -804,13 +778,8 @@ func (w *ObjectNotExistsWaiter) WaitForOutput(ctx context.Context, params *HeadO func objectNotExistsStateRetryable(ctx context.Context, input *HeadObjectInput, output *HeadObjectOutput, err error) (bool, error) { if err != nil { - var apiErr smithy.APIError - ok := errors.As(err, &apiErr) - if !ok { - return false, fmt.Errorf("expected err to be of type smithy.APIError, got %w", err) - } - - if "NotFound" == apiErr.ErrorCode() { + var errorType *types.NotFound + if errors.As(err, &errorType) { return false, nil } } @@ -827,8 +796,9 @@ func newServiceMetadataMiddleware_opHeadObject(region string) *awsmiddleware.Reg } } -// getHeadObjectBucketMember returns a pointer to string denoting a provided bucket -// member valueand a boolean indicating if the input has a modeled bucket name, +// getHeadObjectBucketMember returns a pointer to string denoting a provided +// bucket member valueand a boolean indicating if the input has a modeled bucket +// name, func getHeadObjectBucketMember(input interface{}) (*string, bool) { in := input.(*HeadObjectInput) if in.Bucket == nil { @@ -882,3 +852,139 @@ func addHeadObjectPayloadAsUnsigned(stack *middleware.Stack, options Options) er v4.RemoveComputePayloadSHA256Middleware(stack) return v4.AddUnsignedPayloadMiddleware(stack) } + +type opHeadObjectResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opHeadObjectResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opHeadObjectResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*HeadObjectInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addHeadObjectResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opHeadObjectResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketAnalyticsConfigurations.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketAnalyticsConfigurations.go index 0a0373f29..99ad3827c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketAnalyticsConfigurations.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketAnalyticsConfigurations.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -17,33 +23,21 @@ import ( // does not return more than 100 configurations at a time. You should always check // the IsTruncated element in the response. If there are no more configurations to // list, IsTruncated is set to false. If there are more configurations to list, -// IsTruncated is set to true, and there will be a value in NextContinuationToken. +// IsTruncated is set to true, and there will be a value in NextContinuationToken . // You use the NextContinuationToken value to continue the pagination of the list // by passing the value in continuation-token in the request to GET the next page. // To use this operation, you must have permissions to perform the // s3:GetAnalyticsConfiguration action. The bucket owner has this permission by // default. The bucket owner can grant this permission to others. For more // information about permissions, see Permissions Related to Bucket Subresource -// Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// For information about Amazon S3 analytics feature, see Amazon S3 Analytics – -// Storage Class Analysis -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/analytics-storage-class.html). -// The following operations are related to ListBucketAnalyticsConfigurations: -// -// * -// GetBucketAnalyticsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAnalyticsConfiguration.html) -// -// * -// DeleteBucketAnalyticsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketAnalyticsConfiguration.html) -// -// * -// PutBucketAnalyticsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAnalyticsConfiguration.html) +// Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . For information about Amazon S3 analytics feature, see Amazon S3 Analytics – +// Storage Class Analysis (https://docs.aws.amazon.com/AmazonS3/latest/dev/analytics-storage-class.html) +// . The following operations are related to ListBucketAnalyticsConfigurations : +// - GetBucketAnalyticsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAnalyticsConfiguration.html) +// - DeleteBucketAnalyticsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketAnalyticsConfiguration.html) +// - PutBucketAnalyticsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAnalyticsConfiguration.html) func (c *Client) ListBucketAnalyticsConfigurations(ctx context.Context, params *ListBucketAnalyticsConfigurationsInput, optFns ...func(*Options)) (*ListBucketAnalyticsConfigurationsOutput, error) { if params == nil { params = &ListBucketAnalyticsConfigurationsInput{} @@ -94,7 +88,7 @@ type ListBucketAnalyticsConfigurationsOutput struct { // NextContinuationToken is sent when isTruncated is true, which indicates that // there are more analytics configurations to list. The next request must include - // this NextContinuationToken. The token is obfuscated and is not a usable value. + // this NextContinuationToken . The token is obfuscated and is not a usable value. NextContinuationToken *string // Metadata pertaining to the operation's result. @@ -112,6 +106,9 @@ func (c *Client) addOperationListBucketAnalyticsConfigurationsMiddlewares(stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -139,7 +136,7 @@ func (c *Client) addOperationListBucketAnalyticsConfigurationsMiddlewares(stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -151,6 +148,9 @@ func (c *Client) addOperationListBucketAnalyticsConfigurationsMiddlewares(stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addListBucketAnalyticsConfigurationsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpListBucketAnalyticsConfigurationsValidationMiddleware(stack); err != nil { return err } @@ -160,6 +160,9 @@ func (c *Client) addOperationListBucketAnalyticsConfigurationsMiddlewares(stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addListBucketAnalyticsConfigurationsUpdateEndpoint(stack, options); err != nil { return err } @@ -175,9 +178,22 @@ func (c *Client) addOperationListBucketAnalyticsConfigurationsMiddlewares(stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *ListBucketAnalyticsConfigurationsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opListBucketAnalyticsConfigurations(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -212,3 +228,139 @@ func addListBucketAnalyticsConfigurationsUpdateEndpoint(stack *middleware.Stack, DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opListBucketAnalyticsConfigurationsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListBucketAnalyticsConfigurationsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListBucketAnalyticsConfigurationsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*ListBucketAnalyticsConfigurationsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListBucketAnalyticsConfigurationsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListBucketAnalyticsConfigurationsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketIntelligentTieringConfigurations.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketIntelligentTieringConfigurations.go index 972a69c99..74eff1968 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketIntelligentTieringConfigurations.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketIntelligentTieringConfigurations.go @@ -4,16 +4,22 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Lists the S3 Intelligent-Tiering configuration from the specified bucket. The S3 -// Intelligent-Tiering storage class is designed to optimize storage costs by +// Lists the S3 Intelligent-Tiering configuration from the specified bucket. The +// S3 Intelligent-Tiering storage class is designed to optimize storage costs by // automatically moving data to the most cost-effective storage access tier, // without performance impact or operational overhead. S3 Intelligent-Tiering // delivers automatic cost savings in three low latency and high throughput access @@ -25,21 +31,11 @@ import ( // monitored and not eligible for auto-tiering. Smaller objects can be stored, but // they are always charged at the Frequent Access tier rates in the S3 // Intelligent-Tiering storage class. For more information, see Storage class for -// automatically optimizing frequently and infrequently accessed objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access). -// Operations related to ListBucketIntelligentTieringConfigurations include: -// -// * -// DeleteBucketIntelligentTieringConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketIntelligentTieringConfiguration.html) -// -// * -// PutBucketIntelligentTieringConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketIntelligentTieringConfiguration.html) -// -// * -// GetBucketIntelligentTieringConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketIntelligentTieringConfiguration.html) +// automatically optimizing frequently and infrequently accessed objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access) +// . Operations related to ListBucketIntelligentTieringConfigurations include: +// - DeleteBucketIntelligentTieringConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketIntelligentTieringConfiguration.html) +// - PutBucketIntelligentTieringConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketIntelligentTieringConfiguration.html) +// - GetBucketIntelligentTieringConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketIntelligentTieringConfiguration.html) func (c *Client) ListBucketIntelligentTieringConfigurations(ctx context.Context, params *ListBucketIntelligentTieringConfigurationsInput, optFns ...func(*Options)) (*ListBucketIntelligentTieringConfigurationsOutput, error) { if params == nil { params = &ListBucketIntelligentTieringConfigurationsInput{} @@ -104,6 +100,9 @@ func (c *Client) addOperationListBucketIntelligentTieringConfigurationsMiddlewar if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -131,7 +130,7 @@ func (c *Client) addOperationListBucketIntelligentTieringConfigurationsMiddlewar if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -143,6 +142,9 @@ func (c *Client) addOperationListBucketIntelligentTieringConfigurationsMiddlewar if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addListBucketIntelligentTieringConfigurationsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpListBucketIntelligentTieringConfigurationsValidationMiddleware(stack); err != nil { return err } @@ -152,6 +154,9 @@ func (c *Client) addOperationListBucketIntelligentTieringConfigurationsMiddlewar if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addListBucketIntelligentTieringConfigurationsUpdateEndpoint(stack, options); err != nil { return err } @@ -167,9 +172,22 @@ func (c *Client) addOperationListBucketIntelligentTieringConfigurationsMiddlewar if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *ListBucketIntelligentTieringConfigurationsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opListBucketIntelligentTieringConfigurations(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -204,3 +222,139 @@ func addListBucketIntelligentTieringConfigurationsUpdateEndpoint(stack *middlewa DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opListBucketIntelligentTieringConfigurationsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListBucketIntelligentTieringConfigurationsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListBucketIntelligentTieringConfigurationsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*ListBucketIntelligentTieringConfigurationsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListBucketIntelligentTieringConfigurationsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListBucketIntelligentTieringConfigurationsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketInventoryConfigurations.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketInventoryConfigurations.go index e6c8c79a8..fd2cf048a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketInventoryConfigurations.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketInventoryConfigurations.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -17,32 +23,20 @@ import ( // and does not return more than 100 configurations at a time. Always check the // IsTruncated element in the response. If there are no more configurations to // list, IsTruncated is set to false. If there are more configurations to list, -// IsTruncated is set to true, and there is a value in NextContinuationToken. You +// IsTruncated is set to true, and there is a value in NextContinuationToken . You // use the NextContinuationToken value to continue the pagination of the list by // passing the value in continuation-token in the request to GET the next page. To // use this operation, you must have permissions to perform the // s3:GetInventoryConfiguration action. The bucket owner has this permission by // default. The bucket owner can grant this permission to others. For more // information about permissions, see Permissions Related to Bucket Subresource -// Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// For information about the Amazon S3 inventory feature, see Amazon S3 Inventory -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html) The -// following operations are related to ListBucketInventoryConfigurations: -// -// * -// GetBucketInventoryConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketInventoryConfiguration.html) -// -// * -// DeleteBucketInventoryConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketInventoryConfiguration.html) -// -// * -// PutBucketInventoryConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketInventoryConfiguration.html) +// Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . For information about the Amazon S3 inventory feature, see Amazon S3 Inventory (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html) +// The following operations are related to ListBucketInventoryConfigurations : +// - GetBucketInventoryConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketInventoryConfiguration.html) +// - DeleteBucketInventoryConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketInventoryConfiguration.html) +// - PutBucketInventoryConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketInventoryConfiguration.html) func (c *Client) ListBucketInventoryConfigurations(ctx context.Context, params *ListBucketInventoryConfigurationsInput, optFns ...func(*Options)) (*ListBucketInventoryConfigurationsOutput, error) { if params == nil { params = &ListBucketInventoryConfigurationsInput{} @@ -88,9 +82,9 @@ type ListBucketInventoryConfigurationsOutput struct { // The list of inventory configurations for a bucket. InventoryConfigurationList []types.InventoryConfiguration - // Tells whether the returned list of inventory configurations is complete. A value - // of true indicates that the list is not complete and the NextContinuationToken is - // provided for a subsequent request. + // Tells whether the returned list of inventory configurations is complete. A + // value of true indicates that the list is not complete and the + // NextContinuationToken is provided for a subsequent request. IsTruncated bool // The marker used to continue this inventory configuration listing. Use the @@ -113,6 +107,9 @@ func (c *Client) addOperationListBucketInventoryConfigurationsMiddlewares(stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -140,7 +137,7 @@ func (c *Client) addOperationListBucketInventoryConfigurationsMiddlewares(stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -152,6 +149,9 @@ func (c *Client) addOperationListBucketInventoryConfigurationsMiddlewares(stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addListBucketInventoryConfigurationsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpListBucketInventoryConfigurationsValidationMiddleware(stack); err != nil { return err } @@ -161,6 +161,9 @@ func (c *Client) addOperationListBucketInventoryConfigurationsMiddlewares(stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addListBucketInventoryConfigurationsUpdateEndpoint(stack, options); err != nil { return err } @@ -176,9 +179,22 @@ func (c *Client) addOperationListBucketInventoryConfigurationsMiddlewares(stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *ListBucketInventoryConfigurationsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opListBucketInventoryConfigurations(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -213,3 +229,139 @@ func addListBucketInventoryConfigurationsUpdateEndpoint(stack *middleware.Stack, DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opListBucketInventoryConfigurationsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListBucketInventoryConfigurationsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListBucketInventoryConfigurationsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*ListBucketInventoryConfigurationsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListBucketInventoryConfigurationsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListBucketInventoryConfigurationsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketMetricsConfigurations.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketMetricsConfigurations.go index 50b207af6..45e145e84 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketMetricsConfigurations.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBucketMetricsConfigurations.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -16,35 +22,23 @@ import ( // only for the request metrics of the bucket and do not provide information on // daily storage metrics. You can have up to 1,000 configurations per bucket. This // action supports list pagination and does not return more than 100 configurations -// at a time. Always check the IsTruncated element in the response. If there are no -// more configurations to list, IsTruncated is set to false. If there are more +// at a time. Always check the IsTruncated element in the response. If there are +// no more configurations to list, IsTruncated is set to false. If there are more // configurations to list, IsTruncated is set to true, and there is a value in -// NextContinuationToken. You use the NextContinuationToken value to continue the -// pagination of the list by passing the value in continuation-token in the request -// to GET the next page. To use this operation, you must have permissions to -// perform the s3:GetMetricsConfiguration action. The bucket owner has this +// NextContinuationToken . You use the NextContinuationToken value to continue the +// pagination of the list by passing the value in continuation-token in the +// request to GET the next page. To use this operation, you must have permissions +// to perform the s3:GetMetricsConfiguration action. The bucket owner has this // permission by default. The bucket owner can grant this permission to others. For // more information about permissions, see Permissions Related to Bucket -// Subresource Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// For more information about metrics configurations and CloudWatch request -// metrics, see Monitoring Metrics with Amazon CloudWatch -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html). -// The following operations are related to ListBucketMetricsConfigurations: -// -// * -// PutBucketMetricsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html) -// -// * -// GetBucketMetricsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html) -// -// * -// DeleteBucketMetricsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html) +// Subresource Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . For more information about metrics configurations and CloudWatch request +// metrics, see Monitoring Metrics with Amazon CloudWatch (https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html) +// . The following operations are related to ListBucketMetricsConfigurations : +// - PutBucketMetricsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html) +// - GetBucketMetricsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html) +// - DeleteBucketMetricsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html) func (c *Client) ListBucketMetricsConfigurations(ctx context.Context, params *ListBucketMetricsConfigurationsInput, optFns ...func(*Options)) (*ListBucketMetricsConfigurationsOutput, error) { if params == nil { params = &ListBucketMetricsConfigurationsInput{} @@ -116,6 +110,9 @@ func (c *Client) addOperationListBucketMetricsConfigurationsMiddlewares(stack *m if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -143,7 +140,7 @@ func (c *Client) addOperationListBucketMetricsConfigurationsMiddlewares(stack *m if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -155,6 +152,9 @@ func (c *Client) addOperationListBucketMetricsConfigurationsMiddlewares(stack *m if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addListBucketMetricsConfigurationsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpListBucketMetricsConfigurationsValidationMiddleware(stack); err != nil { return err } @@ -164,6 +164,9 @@ func (c *Client) addOperationListBucketMetricsConfigurationsMiddlewares(stack *m if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addListBucketMetricsConfigurationsUpdateEndpoint(stack, options); err != nil { return err } @@ -179,9 +182,22 @@ func (c *Client) addOperationListBucketMetricsConfigurationsMiddlewares(stack *m if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *ListBucketMetricsConfigurationsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opListBucketMetricsConfigurations(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -216,3 +232,139 @@ func addListBucketMetricsConfigurationsUpdateEndpoint(stack *middleware.Stack, o DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opListBucketMetricsConfigurationsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListBucketMetricsConfigurationsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListBucketMetricsConfigurationsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*ListBucketMetricsConfigurationsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListBucketMetricsConfigurationsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListBucketMetricsConfigurationsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBuckets.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBuckets.go index 7a3de38f4..372402269 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBuckets.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListBuckets.go @@ -4,16 +4,25 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns a list of all buckets owned by the authenticated sender of the request. -// To use this operation, you must have the s3:ListAllMyBuckets permission. +// To use this operation, you must have the s3:ListAllMyBuckets permission. For +// information about Amazon S3 buckets, see Creating, configuring, and working +// with Amazon S3 buckets (https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-buckets-s3.html) +// . func (c *Client) ListBuckets(ctx context.Context, params *ListBucketsInput, optFns ...func(*Options)) (*ListBucketsOutput, error) { if params == nil { params = &ListBucketsInput{} @@ -56,6 +65,9 @@ func (c *Client) addOperationListBucketsMiddlewares(stack *middleware.Stack, opt if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -83,7 +95,7 @@ func (c *Client) addOperationListBucketsMiddlewares(stack *middleware.Stack, opt if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -95,12 +107,18 @@ func (c *Client) addOperationListBucketsMiddlewares(stack *middleware.Stack, opt if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addListBucketsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListBuckets(options.Region), middleware.Before); err != nil { return err } if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addListBucketsUpdateEndpoint(stack, options); err != nil { return err } @@ -116,6 +134,12 @@ func (c *Client) addOperationListBucketsMiddlewares(stack *middleware.Stack, opt if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } @@ -143,3 +167,132 @@ func addListBucketsUpdateEndpoint(stack *middleware.Stack, options Options) erro DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opListBucketsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListBucketsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListBucketsResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListBucketsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListBucketsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListMultipartUploads.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListMultipartUploads.go index af281a252..4749ad10b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListMultipartUploads.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListMultipartUploads.go @@ -4,54 +4,43 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// This action lists in-progress multipart uploads. An in-progress multipart upload -// is a multipart upload that has been initiated using the Initiate Multipart -// Upload request, but has not yet been completed or aborted. This action returns -// at most 1,000 multipart uploads in the response. 1,000 multipart uploads is the -// maximum number of uploads a response can include, which is also the default -// value. You can further limit the number of uploads in a response by specifying -// the max-uploads parameter in the response. If additional multipart uploads -// satisfy the list criteria, the response will contain an IsTruncated element with -// the value true. To list the additional multipart uploads, use the key-marker and -// upload-id-marker request parameters. In the response, the uploads are sorted by -// key. If your application has initiated more than one multipart upload using the -// same object key, then uploads in the response are first sorted by key. -// Additionally, uploads are sorted in ascending order within each key by the -// upload initiation time. For more information on multipart uploads, see Uploading -// Objects Using Multipart Upload -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html). For -// information on permissions required to use the multipart upload API, see -// Multipart Upload and Permissions -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html). The -// following operations are related to ListMultipartUploads: -// -// * -// CreateMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) -// -// * -// UploadPart -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) -// -// * -// CompleteMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) -// -// * -// ListParts -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) -// -// * -// AbortMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) +// This action lists in-progress multipart uploads. An in-progress multipart +// upload is a multipart upload that has been initiated using the Initiate +// Multipart Upload request, but has not yet been completed or aborted. This action +// returns at most 1,000 multipart uploads in the response. 1,000 multipart uploads +// is the maximum number of uploads a response can include, which is also the +// default value. You can further limit the number of uploads in a response by +// specifying the max-uploads parameter in the response. If additional multipart +// uploads satisfy the list criteria, the response will contain an IsTruncated +// element with the value true. To list the additional multipart uploads, use the +// key-marker and upload-id-marker request parameters. In the response, the +// uploads are sorted by key. If your application has initiated more than one +// multipart upload using the same object key, then uploads in the response are +// first sorted by key. Additionally, uploads are sorted in ascending order within +// each key by the upload initiation time. For more information on multipart +// uploads, see Uploading Objects Using Multipart Upload (https://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html) +// . For information on permissions required to use the multipart upload API, see +// Multipart Upload and Permissions (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html) +// . The following operations are related to ListMultipartUploads : +// - CreateMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) +// - UploadPart (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) +// - CompleteMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) +// - ListParts (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) +// - AbortMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) func (c *Client) ListMultipartUploads(ctx context.Context, params *ListMultipartUploadsInput, optFns ...func(*Options)) (*ListMultipartUploadsOutput, error) { if params == nil { params = &ListMultipartUploadsInput{} @@ -75,34 +64,32 @@ type ListMultipartUploadsInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string // Character you use to group keys. All keys that contain the same string between // the prefix, if specified, and the first occurrence of the delimiter after the - // prefix are grouped under a single result element, CommonPrefixes. If you don't + // prefix are grouped under a single result element, CommonPrefixes . If you don't // specify the prefix parameter, then the substring starts at the beginning of the // key. The keys that are grouped under CommonPrefixes result element are not // returned elsewhere in the response. Delimiter *string // Requests Amazon S3 to encode the object keys in the response and specifies the - // encoding method to use. An object key may contain any Unicode character; - // however, XML 1.0 parser cannot parse some characters, such as characters with an - // ASCII value from 0 to 10. For characters that are not supported in XML 1.0, you - // can add this parameter to request that Amazon S3 encode the keys in the + // encoding method to use. An object key can contain any Unicode character; + // however, the XML 1.0 parser cannot parse some characters, such as characters + // with an ASCII value from 0 to 10. For characters that are not supported in XML + // 1.0, you can add this parameter to request that Amazon S3 encode the keys in the // response. EncodingType types.EncodingType @@ -111,12 +98,13 @@ type ListMultipartUploadsInput struct { // (access denied). ExpectedBucketOwner *string - // Together with upload-id-marker, this parameter specifies the multipart upload - // after which listing should begin. If upload-id-marker is not specified, only the - // keys lexicographically greater than the specified key-marker will be included in - // the list. If upload-id-marker is specified, any multipart uploads for a key - // equal to the key-marker might also be included, provided those multipart uploads - // have upload IDs lexicographically greater than the specified upload-id-marker. + // Together with upload-id-marker , this parameter specifies the multipart upload + // after which listing should begin. If upload-id-marker is not specified, only + // the keys lexicographically greater than the specified key-marker will be + // included in the list. If upload-id-marker is specified, any multipart uploads + // for a key equal to the key-marker might also be included, provided those + // multipart uploads have upload IDs lexicographically greater than the specified + // upload-id-marker . KeyMarker *string // Sets the maximum number of multipart uploads, from 1 to 1,000, to return in the @@ -126,15 +114,24 @@ type ListMultipartUploadsInput struct { // Lists in-progress uploads only for those keys that begin with the specified // prefix. You can use prefixes to separate a bucket into different grouping of - // keys. (You can think of using prefix to make groups in the same way you'd use a - // folder in a file system.) + // keys. (You can think of using prefix to make groups in the same way that you'd + // use a folder in a file system.) Prefix *string + // Confirms that the requester knows that they will be charged for the request. + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // in the Amazon S3 User Guide. + RequestPayer types.RequestPayer + // Together with key-marker, specifies the multipart upload after which listing // should begin. If key-marker is not specified, the upload-id-marker parameter is // ignored. Otherwise, any multipart uploads for a key equal to the key-marker // might be included in the list only if they have an upload ID lexicographically - // greater than the specified upload-id-marker. + // greater than the specified upload-id-marker . UploadIdMarker *string noSmithyDocumentSerde @@ -146,9 +143,9 @@ type ListMultipartUploadsOutput struct { // return the access point ARN or access point alias if used. Bucket *string - // If you specify a delimiter in the request, then the result returns each distinct - // key prefix containing the delimiter in a CommonPrefixes element. The distinct - // key prefixes are returned in the Prefix child element. + // If you specify a delimiter in the request, then the result returns each + // distinct key prefix containing the delimiter in a CommonPrefixes element. The + // distinct key prefixes are returned in the Prefix child element. CommonPrefixes []types.CommonPrefix // Contains the delimiter you specified in the request. If you don't specify a @@ -156,9 +153,9 @@ type ListMultipartUploadsOutput struct { Delimiter *string // Encoding type used by Amazon S3 to encode object keys in the response. If you - // specify encoding-type request parameter, Amazon S3 includes this element in the - // response, and returns encoded key name values in the following response - // elements: Delimiter, KeyMarker, Prefix, NextKeyMarker, Key. + // specify the encoding-type request parameter, Amazon S3 includes this element in + // the response, and returns encoded key name values in the following response + // elements: Delimiter , KeyMarker , Prefix , NextKeyMarker , Key . EncodingType types.EncodingType // Indicates whether the returned list of multipart uploads is truncated. A value @@ -186,6 +183,10 @@ type ListMultipartUploadsOutput struct { // prefix. The result contains only keys starting with the specified prefix. Prefix *string + // If present, indicates that the requester was successfully charged for the + // request. + RequestCharged types.RequestCharged + // Upload ID after which listing began. UploadIdMarker *string @@ -208,6 +209,9 @@ func (c *Client) addOperationListMultipartUploadsMiddlewares(stack *middleware.S if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -235,7 +239,7 @@ func (c *Client) addOperationListMultipartUploadsMiddlewares(stack *middleware.S if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -247,6 +251,9 @@ func (c *Client) addOperationListMultipartUploadsMiddlewares(stack *middleware.S if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addListMultipartUploadsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpListMultipartUploadsValidationMiddleware(stack); err != nil { return err } @@ -256,6 +263,9 @@ func (c *Client) addOperationListMultipartUploadsMiddlewares(stack *middleware.S if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addListMultipartUploadsUpdateEndpoint(stack, options); err != nil { return err } @@ -271,9 +281,22 @@ func (c *Client) addOperationListMultipartUploadsMiddlewares(stack *middleware.S if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *ListMultipartUploadsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opListMultipartUploads(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -308,3 +331,139 @@ func addListMultipartUploadsUpdateEndpoint(stack *middleware.Stack, options Opti DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opListMultipartUploadsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListMultipartUploadsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListMultipartUploadsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*ListMultipartUploadsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListMultipartUploadsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListMultipartUploadsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListObjectVersions.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListObjectVersions.go index f2d2b9fa9..00ef2e9ee 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListObjectVersions.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListObjectVersions.go @@ -4,38 +4,33 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Returns metadata about all versions of the objects in a bucket. You can also use -// request parameters as selection criteria to return metadata about a subset of -// all the object versions. To use this operation, you must have permissions to -// perform the s3:ListBucketVersions action. Be aware of the name difference. A 200 -// OK response can contain valid or invalid XML. Make sure to design your +// Returns metadata about all versions of the objects in a bucket. You can also +// use request parameters as selection criteria to return metadata about a subset +// of all the object versions. To use this operation, you must have permission to +// perform the s3:ListBucketVersions action. Be aware of the name difference. A +// 200 OK response can contain valid or invalid XML. Make sure to design your // application to parse the contents of the response and handle it appropriately. // To use this operation, you must have READ access to the bucket. This action is // not supported by Amazon S3 on Outposts. The following operations are related to -// ListObjectVersions: -// -// * ListObjectsV2 -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html) -// -// * -// GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) -// -// * -// PutObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) -// -// * -// DeleteObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) +// ListObjectVersions : +// - ListObjectsV2 (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html) +// - GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// - PutObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) +// - DeleteObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) func (c *Client) ListObjectVersions(ctx context.Context, params *ListObjectVersionsInput, optFns ...func(*Options)) (*ListObjectVersionsOutput, error) { if params == nil { params = &ListObjectVersionsInput{} @@ -58,18 +53,18 @@ type ListObjectVersionsInput struct { // This member is required. Bucket *string - // A delimiter is a character that you specify to group keys. All keys that contain - // the same string between the prefix and the first occurrence of the delimiter are - // grouped under a single result element in CommonPrefixes. These groups are - // counted as one result against the max-keys limitation. These keys are not - // returned elsewhere in the response. + // A delimiter is a character that you specify to group keys. All keys that + // contain the same string between the prefix and the first occurrence of the + // delimiter are grouped under a single result element in CommonPrefixes . These + // groups are counted as one result against the max-keys limitation. These keys + // are not returned elsewhere in the response. Delimiter *string // Requests Amazon S3 to encode the object keys in the response and specifies the - // encoding method to use. An object key may contain any Unicode character; - // however, XML 1.0 parser cannot parse some characters, such as characters with an - // ASCII value from 0 to 10. For characters that are not supported in XML 1.0, you - // can add this parameter to request that Amazon S3 encode the keys in the + // encoding method to use. An object key can contain any Unicode character; + // however, the XML 1.0 parser cannot parse some characters, such as characters + // with an ASCII value from 0 to 10. For characters that are not supported in XML + // 1.0, you can add this parameter to request that Amazon S3 encode the keys in the // response. EncodingType types.EncodingType @@ -81,20 +76,33 @@ type ListObjectVersionsInput struct { // Specifies the key to start with when listing objects in a bucket. KeyMarker *string - // Sets the maximum number of keys returned in the response. By default the action - // returns up to 1,000 key names. The response might contain fewer keys but will - // never contain more. If additional keys satisfy the search criteria, but were not - // returned because max-keys was exceeded, the response contains true. To return - // the additional keys, see key-marker and version-id-marker. + // Sets the maximum number of keys returned in the response. By default, the + // action returns up to 1,000 key names. The response might contain fewer keys but + // will never contain more. If additional keys satisfy the search criteria, but + // were not returned because max-keys was exceeded, the response contains true . To + // return the additional keys, see key-marker and version-id-marker . MaxKeys int32 + // Specifies the optional fields that you want returned in the response. Fields + // that you do not specify are not returned. + OptionalObjectAttributes []types.OptionalObjectAttributes + // Use this parameter to select only those keys that begin with the specified // prefix. You can use prefixes to separate a bucket into different groupings of - // keys. (You can think of using prefix to make groups in the same way you'd use a - // folder in a file system.) You can use prefix with delimiter to roll up numerous - // objects into a single result under CommonPrefixes. + // keys. (You can think of using prefix to make groups in the same way that you'd + // use a folder in a file system.) You can use prefix with delimiter to roll up + // numerous objects into a single result under CommonPrefixes . Prefix *string + // Confirms that the requester knows that they will be charged for the request. + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // in the Amazon S3 User Guide. + RequestPayer types.RequestPayer + // Specifies the object version you want to start listing from. VersionIdMarker *string @@ -113,19 +121,19 @@ type ListObjectVersionsOutput struct { // The delimiter grouping the included keys. A delimiter is a character that you // specify to group keys. All keys that contain the same string between the prefix // and the first occurrence of the delimiter are grouped under a single result - // element in CommonPrefixes. These groups are counted as one result against the + // element in CommonPrefixes . These groups are counted as one result against the // max-keys limitation. These keys are not returned elsewhere in the response. Delimiter *string // Encoding type used by Amazon S3 to encode object key names in the XML response. - // If you specify encoding-type request parameter, Amazon S3 includes this element - // in the response, and returns encoded key name values in the following response - // elements: KeyMarker, NextKeyMarker, Prefix, Key, and Delimiter. + // If you specify the encoding-type request parameter, Amazon S3 includes this + // element in the response, and returns encoded key name values in the following + // response elements: KeyMarker, NextKeyMarker, Prefix, Key , and Delimiter . EncodingType types.EncodingType // A flag that indicates whether Amazon S3 returned all of the results that // satisfied the search criteria. If your results were truncated, you can make a - // follow-up paginated request using the NextKeyMarker and NextVersionIdMarker + // follow-up paginated request by using the NextKeyMarker and NextVersionIdMarker // response parameters as a starting place in another request to return the rest of // the results. IsTruncated bool @@ -139,12 +147,12 @@ type ListObjectVersionsOutput struct { // The bucket name. Name *string - // When the number of responses exceeds the value of MaxKeys, NextKeyMarker + // When the number of responses exceeds the value of MaxKeys , NextKeyMarker // specifies the first key not returned that satisfies the search criteria. Use // this value for the key-marker request parameter in a subsequent request. NextKeyMarker *string - // When the number of responses exceeds the value of MaxKeys, NextVersionIdMarker + // When the number of responses exceeds the value of MaxKeys , NextVersionIdMarker // specifies the first object version not returned that satisfies the search // criteria. Use this value for the version-id-marker request parameter in a // subsequent request. @@ -153,6 +161,10 @@ type ListObjectVersionsOutput struct { // Selects objects that start with the value supplied by this parameter. Prefix *string + // If present, indicates that the requester was successfully charged for the + // request. + RequestCharged types.RequestCharged + // Marks the last version of the key returned in a truncated response. VersionIdMarker *string @@ -174,6 +186,9 @@ func (c *Client) addOperationListObjectVersionsMiddlewares(stack *middleware.Sta if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -201,7 +216,7 @@ func (c *Client) addOperationListObjectVersionsMiddlewares(stack *middleware.Sta if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -213,6 +228,9 @@ func (c *Client) addOperationListObjectVersionsMiddlewares(stack *middleware.Sta if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addListObjectVersionsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpListObjectVersionsValidationMiddleware(stack); err != nil { return err } @@ -222,6 +240,9 @@ func (c *Client) addOperationListObjectVersionsMiddlewares(stack *middleware.Sta if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addListObjectVersionsUpdateEndpoint(stack, options); err != nil { return err } @@ -237,9 +258,22 @@ func (c *Client) addOperationListObjectVersionsMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *ListObjectVersionsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opListObjectVersions(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -274,3 +308,139 @@ func addListObjectVersionsUpdateEndpoint(stack *middleware.Stack, options Option DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opListObjectVersionsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListObjectVersionsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListObjectVersionsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*ListObjectVersionsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListObjectVersionsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListObjectVersionsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListObjects.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListObjects.go index b2d83ff74..19821bba2 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListObjects.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListObjects.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -17,30 +23,14 @@ import ( // bucket. A 200 OK response can contain valid or invalid XML. Be sure to design // your application to parse the contents of the response and handle it // appropriately. This action has been revised. We recommend that you use the newer -// version, ListObjectsV2 -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html), when -// developing applications. For backward compatibility, Amazon S3 continues to -// support ListObjects. The following operations are related to ListObjects: -// -// * -// ListObjectsV2 -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html) -// -// * -// GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) -// -// * -// PutObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) -// -// * -// CreateBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) -// -// * -// ListBuckets -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html) +// version, ListObjectsV2 (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html) +// , when developing applications. For backward compatibility, Amazon S3 continues +// to support ListObjects . The following operations are related to ListObjects : +// - ListObjectsV2 (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html) +// - GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// - PutObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) +// - CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) +// - ListBuckets (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html) func (c *Client) ListObjects(ctx context.Context, params *ListObjectsInput, optFns ...func(*Options)) (*ListObjectsOutput, error) { if params == nil { params = &ListObjectsInput{} @@ -64,29 +54,27 @@ type ListObjectsInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string - // A delimiter is a character you use to group keys. + // A delimiter is a character that you use to group keys. Delimiter *string // Requests Amazon S3 to encode the object keys in the response and specifies the - // encoding method to use. An object key may contain any Unicode character; - // however, XML 1.0 parser cannot parse some characters, such as characters with an - // ASCII value from 0 to 10. For characters that are not supported in XML 1.0, you - // can add this parameter to request that Amazon S3 encode the keys in the + // encoding method to use. An object key can contain any Unicode character; + // however, the XML 1.0 parser cannot parse some characters, such as characters + // with an ASCII value from 0 to 10. For characters that are not supported in XML + // 1.0, you can add this parameter to request that Amazon S3 encode the keys in the // response. EncodingType types.EncodingType @@ -99,11 +87,15 @@ type ListObjectsInput struct { // listing after this specified key. Marker can be any key in the bucket. Marker *string - // Sets the maximum number of keys returned in the response. By default the action - // returns up to 1,000 key names. The response might contain fewer keys but will - // never contain more. + // Sets the maximum number of keys returned in the response. By default, the + // action returns up to 1,000 key names. The response might contain fewer keys but + // will never contain more. MaxKeys int32 + // Specifies the optional fields that you want returned in the response. Fields + // that you do not specify are not returned. + OptionalObjectAttributes []types.OptionalObjectAttributes + // Limits the response to keys that begin with the specified prefix. Prefix *string @@ -122,10 +114,10 @@ type ListObjectsOutput struct { // CommonPrefixes only if you specify a delimiter. CommonPrefixes contains all (if // there are any) keys between Prefix and the next occurrence of the string // specified by the delimiter. CommonPrefixes lists keys that act like - // subdirectories in the directory specified by Prefix. For example, if the prefix - // is notes/ and the delimiter is a slash (/) as in notes/summer/july, the common - // prefix is notes/summer/. All of the keys that roll up into a common prefix count - // as a single return when calculating the number of returns. + // subdirectories in the directory specified by Prefix . For example, if the prefix + // is notes/ and the delimiter is a slash ( / ), as in notes/summer/july , the + // common prefix is notes/summer/ . All of the keys that roll up into a common + // prefix count as a single return when calculating the number of returns. CommonPrefixes []types.CommonPrefix // Metadata about each object returned. @@ -145,8 +137,8 @@ type ListObjectsOutput struct { // satisfied the search criteria. IsTruncated bool - // Indicates where in the bucket listing begins. Marker is included in the response - // if it was sent with the request. + // Indicates where in the bucket listing begins. Marker is included in the + // response if it was sent with the request. Marker *string // The maximum number of keys returned in the response body. @@ -155,18 +147,23 @@ type ListObjectsOutput struct { // The bucket name. Name *string - // When response is truncated (the IsTruncated element value in the response is - // true), you can use the key name in this field as marker in the subsequent - // request to get next set of objects. Amazon S3 lists objects in alphabetical - // order Note: This element is returned only if you have delimiter request - // parameter specified. If response does not include the NextMarker and it is - // truncated, you can use the value of the last Key in the response as the marker - // in the subsequent request to get the next set of object keys. + // When the response is truncated (the IsTruncated element value in the response + // is true ), you can use the key name in this field as the marker parameter in + // the subsequent request to get the next set of objects. Amazon S3 lists objects + // in alphabetical order. This element is returned only if you have the delimiter + // request parameter specified. If the response does not include the NextMarker + // element and it is truncated, you can use the value of the last Key element in + // the response as the marker parameter in the subsequent request to get the next + // set of object keys. NextMarker *string // Keys that begin with the indicated prefix. Prefix *string + // If present, indicates that the requester was successfully charged for the + // request. + RequestCharged types.RequestCharged + // Metadata pertaining to the operation's result. ResultMetadata middleware.Metadata @@ -182,6 +179,9 @@ func (c *Client) addOperationListObjectsMiddlewares(stack *middleware.Stack, opt if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -209,7 +209,7 @@ func (c *Client) addOperationListObjectsMiddlewares(stack *middleware.Stack, opt if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -221,6 +221,9 @@ func (c *Client) addOperationListObjectsMiddlewares(stack *middleware.Stack, opt if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addListObjectsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpListObjectsValidationMiddleware(stack); err != nil { return err } @@ -230,6 +233,9 @@ func (c *Client) addOperationListObjectsMiddlewares(stack *middleware.Stack, opt if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addListObjectsUpdateEndpoint(stack, options); err != nil { return err } @@ -245,9 +251,22 @@ func (c *Client) addOperationListObjectsMiddlewares(stack *middleware.Stack, opt if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *ListObjectsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opListObjects(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -282,3 +301,139 @@ func addListObjectsUpdateEndpoint(stack *middleware.Stack, options Options) erro DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opListObjectsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListObjectsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListObjectsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*ListObjectsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListObjectsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListObjectsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListObjectsV2.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListObjectsV2.go index 6214d2471..db25aadf5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListObjectsV2.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListObjectsV2.go @@ -4,11 +4,16 @@ package s3 import ( "context" + "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -19,35 +24,23 @@ import ( // Make sure to design your application to parse the contents of the response and // handle it appropriately. Objects are returned sorted in an ascending order of // the respective key names in the list. For more information about listing -// objects, see Listing object keys programmatically -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/ListingKeysUsingAPIs.html) -// To use this operation, you must have READ access to the bucket. To use this -// action in an Identity and Access Management (IAM) policy, you must have -// permissions to perform the s3:ListBucket action. The bucket owner has this -// permission by default and can grant this permission to others. For more -// information about permissions, see Permissions Related to Bucket Subresource -// Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// This section describes the latest revision of this action. We recommend that you -// use this revised API for application development. For backward compatibility, -// Amazon S3 continues to support the prior version of this API, ListObjects -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html). To get a -// list of your buckets, see ListBuckets -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html). The -// following operations are related to ListObjectsV2: -// -// * GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) -// -// * -// PutObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) -// -// * -// CreateBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) +// objects, see Listing object keys programmatically (https://docs.aws.amazon.com/AmazonS3/latest/userguide/ListingKeysUsingAPIs.html) +// in the Amazon S3 User Guide. To use this operation, you must have READ access to +// the bucket. To use this action in an Identity and Access Management (IAM) +// policy, you must have permission to perform the s3:ListBucket action. The +// bucket owner has this permission by default and can grant this permission to +// others. For more information about permissions, see Permissions Related to +// Bucket Subresource Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// in the Amazon S3 User Guide. This section describes the latest revision of this +// action. We recommend that you use this revised API operation for application +// development. For backward compatibility, Amazon S3 continues to support the +// prior version of this API operation, ListObjects (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html) +// . To get a list of your buckets, see ListBuckets (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html) +// . The following operations are related to ListObjectsV2 : +// - GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// - PutObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) +// - CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) func (c *Client) ListObjectsV2(ctx context.Context, params *ListObjectsV2Input, optFns ...func(*Options)) (*ListObjectsV2Output, error) { if params == nil { params = &ListObjectsV2Input{} @@ -70,26 +63,24 @@ type ListObjectsV2Input struct { // the form AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When // using this action with an access point through the Amazon Web Services SDKs, you // provide the access point ARN in place of the bucket name. For more information - // about access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // about access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string - // ContinuationToken indicates Amazon S3 that the list is being continued on this - // bucket with a token. ContinuationToken is obfuscated and is not a real key. + // ContinuationToken indicates to Amazon S3 that the list is being continued on + // this bucket with a token. ContinuationToken is obfuscated and is not a real key. ContinuationToken *string - // A delimiter is a character you use to group keys. + // A delimiter is a character that you use to group keys. Delimiter *string // Encoding type used by Amazon S3 to encode object keys in the response. @@ -100,15 +91,20 @@ type ListObjectsV2Input struct { // (access denied). ExpectedBucketOwner *string - // The owner field is not present in listV2 by default, if you want to return owner - // field with each key in the result then set the fetch owner field to true. + // The owner field is not present in ListObjectsV2 by default. If you want to + // return the owner field with each key in the result, then set the FetchOwner + // field to true . FetchOwner bool - // Sets the maximum number of keys returned in the response. By default the action - // returns up to 1,000 key names. The response might contain fewer keys but will - // never contain more. + // Sets the maximum number of keys returned in the response. By default, the + // action returns up to 1,000 key names. The response might contain fewer keys but + // will never contain more. MaxKeys int32 + // Specifies the optional fields that you want returned in the response. Fields + // that you do not specify are not returned. + OptionalObjectAttributes []types.OptionalObjectAttributes + // Limits the response to keys that begin with the specified prefix. Prefix *string @@ -130,11 +126,11 @@ type ListObjectsV2Output struct { // return when calculating the number of returns. A response can contain // CommonPrefixes only if you specify a delimiter. CommonPrefixes contains all (if // there are any) keys between Prefix and the next occurrence of the string - // specified by a delimiter. CommonPrefixes lists keys that act like subdirectories - // in the directory specified by Prefix. For example, if the prefix is notes/ and - // the delimiter is a slash (/) as in notes/summer/july, the common prefix is - // notes/summer/. All of the keys that roll up into a common prefix count as a - // single return when calculating the number of returns. + // specified by a delimiter. CommonPrefixes lists keys that act like + // subdirectories in the directory specified by Prefix . For example, if the prefix + // is notes/ and the delimiter is a slash ( / ) as in notes/summer/july , the + // common prefix is notes/summer/ . All of the keys that roll up into a common + // prefix count as a single return when calculating the number of returns. CommonPrefixes []types.CommonPrefix // Metadata about each object returned. @@ -153,22 +149,22 @@ type ListObjectsV2Output struct { // Encoding type used by Amazon S3 to encode object key names in the XML response. // If you specify the encoding-type request parameter, Amazon S3 includes this // element in the response, and returns encoded key name values in the following - // response elements: Delimiter, Prefix, Key, and StartAfter. + // response elements: Delimiter, Prefix, Key, and StartAfter . EncodingType types.EncodingType // Set to false if all of the results were returned. Set to true if more keys are - // available to return. If the number of results exceeds that specified by MaxKeys, - // all of the results might not be returned. + // available to return. If the number of results exceeds that specified by MaxKeys + // , all of the results might not be returned. IsTruncated bool // KeyCount is the number of keys returned with this request. KeyCount will always - // be less than or equals to MaxKeys field. Say you ask for 50 keys, your result - // will include less than equals 50 keys + // be less than or equal to the MaxKeys field. For example, if you ask for 50 + // keys, your result will include 50 keys or fewer. KeyCount int32 - // Sets the maximum number of keys returned in the response. By default the action - // returns up to 1,000 key names. The response might contain fewer keys but will - // never contain more. + // Sets the maximum number of keys returned in the response. By default, the + // action returns up to 1,000 key names. The response might contain fewer keys but + // will never contain more. MaxKeys int32 // The bucket name. When using this action with an access point, you must direct @@ -176,28 +172,30 @@ type ListObjectsV2Output struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. Name *string // NextContinuationToken is sent when isTruncated is true, which means there are // more keys in the bucket that can be listed. The next list requests to Amazon S3 - // can be continued with this NextContinuationToken. NextContinuationToken is + // can be continued with this NextContinuationToken . NextContinuationToken is // obfuscated and is not a real key NextContinuationToken *string // Keys that begin with the indicated prefix. Prefix *string + // If present, indicates that the requester was successfully charged for the + // request. + RequestCharged types.RequestCharged + // If StartAfter was sent with the request, it is included in the response. StartAfter *string @@ -216,6 +214,9 @@ func (c *Client) addOperationListObjectsV2Middlewares(stack *middleware.Stack, o if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -243,7 +244,7 @@ func (c *Client) addOperationListObjectsV2Middlewares(stack *middleware.Stack, o if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -255,6 +256,9 @@ func (c *Client) addOperationListObjectsV2Middlewares(stack *middleware.Stack, o if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addListObjectsV2ResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpListObjectsV2ValidationMiddleware(stack); err != nil { return err } @@ -264,6 +268,9 @@ func (c *Client) addOperationListObjectsV2Middlewares(stack *middleware.Stack, o if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addListObjectsV2UpdateEndpoint(stack, options); err != nil { return err } @@ -279,9 +286,22 @@ func (c *Client) addOperationListObjectsV2Middlewares(stack *middleware.Stack, o if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *ListObjectsV2Input) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + // ListObjectsV2APIClient is a client that implements the ListObjectsV2 operation. type ListObjectsV2APIClient interface { ListObjectsV2(context.Context, *ListObjectsV2Input, ...func(*Options)) (*ListObjectsV2Output, error) @@ -291,9 +311,9 @@ var _ ListObjectsV2APIClient = (*Client)(nil) // ListObjectsV2PaginatorOptions is the paginator options for ListObjectsV2 type ListObjectsV2PaginatorOptions struct { - // Sets the maximum number of keys returned in the response. By default the action - // returns up to 1,000 key names. The response might contain fewer keys but will - // never contain more. + // Sets the maximum number of keys returned in the response. By default, the + // action returns up to 1,000 key names. The response might contain fewer keys but + // will never contain more. Limit int32 // Set to true if pagination should stop if the service returns a pagination token @@ -406,3 +426,139 @@ func addListObjectsV2UpdateEndpoint(stack *middleware.Stack, options Options) er DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opListObjectsV2ResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListObjectsV2ResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListObjectsV2ResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*ListObjectsV2Input) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListObjectsV2ResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListObjectsV2ResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListParts.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListParts.go index 36675dcd7..14ef6f91f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListParts.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_ListParts.go @@ -4,11 +4,16 @@ package s3 import ( "context" + "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "time" @@ -16,46 +21,26 @@ import ( // Lists the parts that have been uploaded for a specific multipart upload. This // operation must include the upload ID, which you obtain by sending the initiate -// multipart upload request (see CreateMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html)). -// This request returns a maximum of 1,000 uploaded parts. The default number of +// multipart upload request (see CreateMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) +// ). This request returns a maximum of 1,000 uploaded parts. The default number of // parts returned is 1,000 parts. You can restrict the number of parts returned by -// specifying the max-parts request parameter. If your multipart upload consists of -// more than 1,000 parts, the response returns an IsTruncated field with the value -// of true, and a NextPartNumberMarker element. In subsequent ListParts requests -// you can include the part-number-marker query string parameter and set its value -// to the NextPartNumberMarker field value from the previous response. If the -// upload was created using a checksum algorithm, you will need to have permission -// to the kms:Decrypt action for the request to succeed. For more information on -// multipart uploads, see Uploading Objects Using Multipart Upload -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html). For -// information on permissions required to use the multipart upload API, see -// Multipart Upload and Permissions -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html). The -// following operations are related to ListParts: -// -// * CreateMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) -// -// * -// UploadPart -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) -// -// * -// CompleteMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) -// -// * -// AbortMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) -// -// * -// GetObjectAttributes -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) -// -// * -// ListMultipartUploads -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) +// specifying the max-parts request parameter. If your multipart upload consists +// of more than 1,000 parts, the response returns an IsTruncated field with the +// value of true, and a NextPartNumberMarker element. In subsequent ListParts +// requests you can include the part-number-marker query string parameter and set +// its value to the NextPartNumberMarker field value from the previous response. +// If the upload was created using a checksum algorithm, you will need to have +// permission to the kms:Decrypt action for the request to succeed. For more +// information on multipart uploads, see Uploading Objects Using Multipart Upload (https://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html) +// . For information on permissions required to use the multipart upload API, see +// Multipart Upload and Permissions (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html) +// . The following operations are related to ListParts : +// - CreateMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) +// - UploadPart (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) +// - CompleteMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) +// - AbortMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) +// - GetObjectAttributes (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html) +// - ListMultipartUploads (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) func (c *Client) ListParts(ctx context.Context, params *ListPartsInput, optFns ...func(*Options)) (*ListPartsOutput, error) { if params == nil { params = &ListPartsInput{} @@ -79,17 +64,15 @@ type ListPartsInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -112,36 +95,34 @@ type ListPartsInput struct { // Sets the maximum number of parts to return. MaxParts int32 - // Specifies the part after which listing should begin. Only parts with higher part - // numbers will be listed. + // Specifies the part after which listing should begin. Only parts with higher + // part numbers will be listed. PartNumberMarker *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer // The server-side encryption (SSE) algorithm used to encrypt the object. This // parameter is needed only when the object was created using a checksum algorithm. - // For more information, see Protecting data using SSE-C keys - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) + // For more information, see Protecting data using SSE-C keys (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) // in the Amazon S3 User Guide. SSECustomerAlgorithm *string // The server-side encryption (SSE) customer managed key. This parameter is needed // only when the object was created using a checksum algorithm. For more - // information, see Protecting data using SSE-C keys - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) + // information, see Protecting data using SSE-C keys (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) // in the Amazon S3 User Guide. SSECustomerKey *string // The MD5 server-side encryption (SSE) customer managed key. This parameter is // needed only when the object was created using a checksum algorithm. For more - // information, see Protecting data using SSE-C keys - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) + // information, see Protecting data using SSE-C keys (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) // in the Amazon S3 User Guide. SSECustomerKeyMD5 *string @@ -150,15 +131,14 @@ type ListPartsInput struct { type ListPartsOutput struct { - // If the bucket has a lifecycle rule configured with an action to abort incomplete - // multipart uploads and the prefix in the lifecycle rule matches the object name - // in the request, then the response includes this header indicating when the - // initiated multipart upload will become eligible for abort operation. For more - // information, see Aborting Incomplete Multipart Uploads Using a Bucket Lifecycle - // Policy - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config). - // The response will also include the x-amz-abort-rule-id header that will provide - // the ID of the lifecycle configuration rule that defines this action. + // If the bucket has a lifecycle rule configured with an action to abort + // incomplete multipart uploads and the prefix in the lifecycle rule matches the + // object name in the request, then the response includes this header indicating + // when the initiated multipart upload will become eligible for abort operation. + // For more information, see Aborting Incomplete Multipart Uploads Using a Bucket + // Lifecycle Configuration (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config) + // . The response will also include the x-amz-abort-rule-id header that will + // provide the ID of the lifecycle configuration rule that defines this action. AbortDate *time.Time // This header is returned along with the x-amz-abort-date header. It identifies @@ -195,9 +175,9 @@ type ListPartsOutput struct { // subsequent request. NextPartNumberMarker *string - // Container element that identifies the object owner, after the object is created. - // If multipart upload is initiated by an IAM user, this element provides the - // parent account ID and display name. + // Container element that identifies the object owner, after the object is + // created. If multipart upload is initiated by an IAM user, this element provides + // the parent account ID and display name. Owner *types.Owner // When a list is truncated, this element specifies the last part in the list, as @@ -205,8 +185,8 @@ type ListPartsOutput struct { // subsequent request. PartNumberMarker *string - // Container for elements related to a particular part. A response can contain zero - // or more Part elements. + // Container for elements related to a particular part. A response can contain + // zero or more Part elements. Parts []types.Part // If present, indicates that the requester was successfully charged for the @@ -235,6 +215,9 @@ func (c *Client) addOperationListPartsMiddlewares(stack *middleware.Stack, optio if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -262,7 +245,7 @@ func (c *Client) addOperationListPartsMiddlewares(stack *middleware.Stack, optio if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -274,6 +257,9 @@ func (c *Client) addOperationListPartsMiddlewares(stack *middleware.Stack, optio if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addListPartsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpListPartsValidationMiddleware(stack); err != nil { return err } @@ -283,6 +269,9 @@ func (c *Client) addOperationListPartsMiddlewares(stack *middleware.Stack, optio if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addListPartsUpdateEndpoint(stack, options); err != nil { return err } @@ -298,9 +287,22 @@ func (c *Client) addOperationListPartsMiddlewares(stack *middleware.Stack, optio if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *ListPartsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + // ListPartsAPIClient is a client that implements the ListParts operation. type ListPartsAPIClient interface { ListParts(context.Context, *ListPartsInput, ...func(*Options)) (*ListPartsOutput, error) @@ -422,3 +424,139 @@ func addListPartsUpdateEndpoint(stack *middleware.Stack, options Options) error DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opListPartsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListPartsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListPartsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*ListPartsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListPartsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListPartsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketAccelerateConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketAccelerateConfiguration.go index 7875798f2..723273d98 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketAccelerateConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketAccelerateConfiguration.go @@ -4,11 +4,17 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -19,37 +25,23 @@ import ( // perform the s3:PutAccelerateConfiguration action. The bucket owner has this // permission by default. The bucket owner can grant this permission to others. For // more information about permissions, see Permissions Related to Bucket -// Subresource Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// The Transfer Acceleration state of a bucket can be set to one of the following +// Subresource Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . The Transfer Acceleration state of a bucket can be set to one of the following // two values: +// - Enabled – Enables accelerated data transfers to the bucket. +// - Suspended – Disables accelerated data transfers to the bucket. // -// * Enabled – Enables accelerated data transfers to the bucket. -// -// * -// Suspended – Disables accelerated data transfers to the bucket. -// -// The -// GetBucketAccelerateConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAccelerateConfiguration.html) +// The GetBucketAccelerateConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAccelerateConfiguration.html) // action returns the transfer acceleration state of a bucket. After setting the // Transfer Acceleration state of a bucket to Enabled, it might take up to thirty // minutes before the data transfer rates to the bucket increase. The name of the // bucket used for Transfer Acceleration must be DNS-compliant and must not contain // periods ("."). For more information about transfer acceleration, see Transfer -// Acceleration -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html). -// The following operations are related to PutBucketAccelerateConfiguration: -// -// * -// GetBucketAccelerateConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAccelerateConfiguration.html) -// -// * -// CreateBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) +// Acceleration (https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html) +// . The following operations are related to PutBucketAccelerateConfiguration : +// - GetBucketAccelerateConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAccelerateConfiguration.html) +// - CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) func (c *Client) PutBucketAccelerateConfiguration(ctx context.Context, params *PutBucketAccelerateConfigurationInput, optFns ...func(*Options)) (*PutBucketAccelerateConfigurationOutput, error) { if params == nil { params = &PutBucketAccelerateConfigurationInput{} @@ -81,9 +73,8 @@ type PutBucketAccelerateConfigurationInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm @@ -112,6 +103,9 @@ func (c *Client) addOperationPutBucketAccelerateConfigurationMiddlewares(stack * if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -139,7 +133,7 @@ func (c *Client) addOperationPutBucketAccelerateConfigurationMiddlewares(stack * if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -151,6 +145,9 @@ func (c *Client) addOperationPutBucketAccelerateConfigurationMiddlewares(stack * if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketAccelerateConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketAccelerateConfigurationValidationMiddleware(stack); err != nil { return err } @@ -160,6 +157,9 @@ func (c *Client) addOperationPutBucketAccelerateConfigurationMiddlewares(stack * if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketAccelerateConfigurationInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -178,9 +178,22 @@ func (c *Client) addOperationPutBucketAccelerateConfigurationMiddlewares(stack * if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketAccelerateConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketAccelerateConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -235,3 +248,139 @@ func addPutBucketAccelerateConfigurationUpdateEndpoint(stack *middleware.Stack, DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketAccelerateConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketAccelerateConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketAccelerateConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketAccelerateConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketAccelerateConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketAccelerateConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketAcl.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketAcl.go index bc28a9960..bb706bbee 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketAcl.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketAcl.go @@ -4,156 +4,103 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Sets the permissions on an existing bucket using access control lists (ACL). For -// more information, see Using ACLs -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/S3_ACLs_UsingACLs.html). To set -// the ACL of a bucket, you must have WRITE_ACP permission. You can use one of the -// following two ways to set a bucket's permissions: -// -// * Specify the ACL in the -// request body -// -// * Specify permissions using request headers -// -// You cannot specify -// access permission using both the body and the request headers. Depending on your -// application needs, you may choose to set the ACL on a bucket using either the -// request body or the headers. For example, if you have an existing application -// that updates a bucket ACL using the request body, then you can continue to use -// that approach. If your bucket uses the bucket owner enforced setting for S3 -// Object Ownership, ACLs are disabled and no longer affect permissions. You must -// use policies to grant access to your bucket and the objects in it. Requests to -// set ACLs or update ACLs fail and return the AccessControlListNotSupported error -// code. Requests to read ACLs are still supported. For more information, see -// Controlling object ownership -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) -// in the Amazon S3 User Guide. Access Permissions You can set access permissions -// using one of the following methods: -// -// * Specify a canned ACL with the x-amz-acl -// request header. Amazon S3 supports a set of predefined ACLs, known as canned -// ACLs. Each canned ACL has a predefined set of grantees and permissions. Specify -// the canned ACL name as the value of x-amz-acl. If you use this header, you -// cannot use other access control-specific headers in your request. For more -// information, see Canned ACL -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL). -// -// * -// Specify access permissions explicitly with the x-amz-grant-read, -// x-amz-grant-read-acp, x-amz-grant-write-acp, and x-amz-grant-full-control -// headers. When using these headers, you specify explicit access permissions and -// grantees (Amazon Web Services accounts or Amazon S3 groups) who will receive the -// permission. If you use these ACL-specific headers, you cannot use the x-amz-acl -// header to set a canned ACL. These parameters map to the set of permissions that -// Amazon S3 supports in an ACL. For more information, see Access Control List -// (ACL) Overview -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html). You specify -// each grantee as a type=value pair, where the type is one of the following: -// -// * id -// – if the value specified is the canonical user ID of an Amazon Web Services -// account -// -// * uri – if you are granting permissions to a predefined group -// -// * -// emailAddress – if the value specified is the email address of an Amazon Web -// Services account Using email addresses to specify a grantee is only supported in -// the following Amazon Web Services Regions: -// -// * US East (N. Virginia) -// -// * US West -// (N. California) -// -// * US West (Oregon) -// -// * Asia Pacific (Singapore) -// -// * Asia Pacific -// (Sydney) -// -// * Asia Pacific (Tokyo) -// -// * Europe (Ireland) -// -// * South America (São -// Paulo) -// -// For a list of all the Amazon S3 supported Regions and endpoints, see -// Regions and Endpoints -// (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the -// Amazon Web Services General Reference. -// -// For example, the following -// x-amz-grant-write header grants create, overwrite, and delete objects permission -// to LogDelivery group predefined by Amazon S3 and two Amazon Web Services -// accounts identified by their email addresses. x-amz-grant-write: -// uri="http://acs.amazonaws.com/groups/s3/LogDelivery", id="111122223333", -// id="555566667777" -// -// You can use either a canned ACL or specify access permissions -// explicitly. You cannot do both. Grantee Values You can specify the person -// (grantee) to whom you're assigning access rights (using request elements) in the -// following ways: -// -// * By the person's ID: <>ID<><>GranteesEmail<> DisplayName is -// optional and ignored in the request -// -// * By URI: -// <>http://acs.amazonaws.com/groups/global/AuthenticatedUsers<> -// -// * By Email -// address: <>Grantees@email.com<>lt;/Grantee> The grantee is resolved to the -// CanonicalUser and, in a response to a GET Object acl request, appears as the -// CanonicalUser. Using email addresses to specify a grantee is only supported in -// the following Amazon Web Services Regions: -// -// * US East (N. Virginia) -// -// * US West -// (N. California) -// -// * US West (Oregon) -// -// * Asia Pacific (Singapore) -// -// * Asia Pacific -// (Sydney) -// -// * Asia Pacific (Tokyo) -// -// * Europe (Ireland) -// -// * South America (São -// Paulo) -// -// For a list of all the Amazon S3 supported Regions and endpoints, see -// Regions and Endpoints -// (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the -// Amazon Web Services General Reference. -// -// # Related Resources -// -// * CreateBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) -// -// * -// DeleteBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) -// -// * -// GetObjectAcl -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html) +// Sets the permissions on an existing bucket using access control lists (ACL). +// For more information, see Using ACLs (https://docs.aws.amazon.com/AmazonS3/latest/dev/S3_ACLs_UsingACLs.html) +// . To set the ACL of a bucket, you must have WRITE_ACP permission. You can use +// one of the following two ways to set a bucket's permissions: +// - Specify the ACL in the request body +// - Specify permissions using request headers +// +// You cannot specify access permission using both the body and the request +// headers. Depending on your application needs, you may choose to set the ACL on a +// bucket using either the request body or the headers. For example, if you have an +// existing application that updates a bucket ACL using the request body, then you +// can continue to use that approach. If your bucket uses the bucket owner enforced +// setting for S3 Object Ownership, ACLs are disabled and no longer affect +// permissions. You must use policies to grant access to your bucket and the +// objects in it. Requests to set ACLs or update ACLs fail and return the +// AccessControlListNotSupported error code. Requests to read ACLs are still +// supported. For more information, see Controlling object ownership (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) +// in the Amazon S3 User Guide. Permissions You can set access permissions by using +// one of the following methods: +// - Specify a canned ACL with the x-amz-acl request header. Amazon S3 supports a +// set of predefined ACLs, known as canned ACLs. Each canned ACL has a predefined +// set of grantees and permissions. Specify the canned ACL name as the value of +// x-amz-acl . If you use this header, you cannot use other access +// control-specific headers in your request. For more information, see Canned ACL (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL) +// . +// - Specify access permissions explicitly with the x-amz-grant-read , +// x-amz-grant-read-acp , x-amz-grant-write-acp , and x-amz-grant-full-control +// headers. When using these headers, you specify explicit access permissions and +// grantees (Amazon Web Services accounts or Amazon S3 groups) who will receive the +// permission. If you use these ACL-specific headers, you cannot use the +// x-amz-acl header to set a canned ACL. These parameters map to the set of +// permissions that Amazon S3 supports in an ACL. For more information, see +// Access Control List (ACL) Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html) +// . You specify each grantee as a type=value pair, where the type is one of the +// following: +// - id – if the value specified is the canonical user ID of an Amazon Web +// Services account +// - uri – if you are granting permissions to a predefined group +// - emailAddress – if the value specified is the email address of an Amazon Web +// Services account Using email addresses to specify a grantee is only supported in +// the following Amazon Web Services Regions: +// - US East (N. Virginia) +// - US West (N. California) +// - US West (Oregon) +// - Asia Pacific (Singapore) +// - Asia Pacific (Sydney) +// - Asia Pacific (Tokyo) +// - Europe (Ireland) +// - South America (São Paulo) For a list of all the Amazon S3 supported Regions +// and endpoints, see Regions and Endpoints (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) +// in the Amazon Web Services General Reference. For example, the following +// x-amz-grant-write header grants create, overwrite, and delete objects +// permission to LogDelivery group predefined by Amazon S3 and two Amazon Web +// Services accounts identified by their email addresses. x-amz-grant-write: +// uri="http://acs.amazonaws.com/groups/s3/LogDelivery", id="111122223333", +// id="555566667777" +// +// You can use either a canned ACL or specify access permissions explicitly. You +// cannot do both. Grantee Values You can specify the person (grantee) to whom +// you're assigning access rights (using request elements) in the following ways: +// - By the person's ID: <>ID<><>GranteesEmail<> DisplayName is optional and +// ignored in the request +// - By URI: <>http://acs.amazonaws.com/groups/global/AuthenticatedUsers<> +// - By Email address: <>Grantees@email.com<>& The grantee is resolved to the +// CanonicalUser and, in a response to a GET Object acl request, appears as the +// CanonicalUser. Using email addresses to specify a grantee is only supported in +// the following Amazon Web Services Regions: +// - US East (N. Virginia) +// - US West (N. California) +// - US West (Oregon) +// - Asia Pacific (Singapore) +// - Asia Pacific (Sydney) +// - Asia Pacific (Tokyo) +// - Europe (Ireland) +// - South America (São Paulo) For a list of all the Amazon S3 supported Regions +// and endpoints, see Regions and Endpoints (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) +// in the Amazon Web Services General Reference. +// +// The following operations are related to PutBucketAcl : +// - CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) +// - DeleteBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) +// - GetObjectAcl (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html) func (c *Client) PutBucketAcl(ctx context.Context, params *PutBucketAclInput, optFns ...func(*Options)) (*PutBucketAclOutput, error) { if params == nil { params = &PutBucketAclInput{} @@ -186,19 +133,17 @@ type PutBucketAclInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm - // The base64-encoded 128-bit MD5 digest of the data. This header must be used as a - // message integrity check to verify that the request body was not corrupted in - // transit. For more information, go to RFC 1864. - // (http://www.ietf.org/rfc/rfc1864.txt) For requests made using the Amazon Web - // Services Command Line Interface (CLI) or Amazon Web Services SDKs, this field is - // calculated automatically. + // The base64-encoded 128-bit MD5 digest of the data. This header must be used as + // a message integrity check to verify that the request body was not corrupted in + // transit. For more information, go to RFC 1864. (http://www.ietf.org/rfc/rfc1864.txt) + // For requests made using the Amazon Web Services Command Line Interface (CLI) or + // Amazon Web Services SDKs, this field is calculated automatically. ContentMD5 *string // The account ID of the expected bucket owner. If the bucket is owned by a @@ -243,6 +188,9 @@ func (c *Client) addOperationPutBucketAclMiddlewares(stack *middleware.Stack, op if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -270,7 +218,7 @@ func (c *Client) addOperationPutBucketAclMiddlewares(stack *middleware.Stack, op if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -282,6 +230,9 @@ func (c *Client) addOperationPutBucketAclMiddlewares(stack *middleware.Stack, op if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketAclResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketAclValidationMiddleware(stack); err != nil { return err } @@ -291,6 +242,9 @@ func (c *Client) addOperationPutBucketAclMiddlewares(stack *middleware.Stack, op if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketAclInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -309,9 +263,22 @@ func (c *Client) addOperationPutBucketAclMiddlewares(stack *middleware.Stack, op if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketAclInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketAcl(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -366,3 +333,139 @@ func addPutBucketAclUpdateEndpoint(stack *middleware.Stack, options Options) err DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketAclResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketAclResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketAclResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketAclInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketAclResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketAclResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketAnalyticsConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketAnalyticsConfiguration.go index da70d547e..581c5ca46 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketAnalyticsConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketAnalyticsConfiguration.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -22,60 +28,35 @@ import ( // to a destination bucket in a different account. However, the destination bucket // must be in the same Region as the bucket that you are making the PUT analytics // configuration to. For more information, see Amazon S3 Analytics – Storage Class -// Analysis -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/analytics-storage-class.html). -// You must create a bucket policy on the destination bucket where the exported +// Analysis (https://docs.aws.amazon.com/AmazonS3/latest/dev/analytics-storage-class.html) +// . You must create a bucket policy on the destination bucket where the exported // file is written to grant permissions to Amazon S3 to write objects to the // bucket. For an example policy, see Granting Permissions for Amazon S3 Inventory -// and Storage Class Analysis -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html#example-bucket-policies-use-case-9). -// To use this operation, you must have permissions to perform the +// and Storage Class Analysis (https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html#example-bucket-policies-use-case-9) +// . To use this operation, you must have permissions to perform the // s3:PutAnalyticsConfiguration action. The bucket owner has this permission by // default. The bucket owner can grant this permission to others. For more // information about permissions, see Permissions Related to Bucket Subresource -// Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// Special Errors +// Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . PutBucketAnalyticsConfiguration has the following special errors: +// - HTTP Error: HTTP 400 Bad Request +// - Code: InvalidArgument +// - Cause: Invalid argument. +// - HTTP Error: HTTP 400 Bad Request +// - Code: TooManyConfigurations +// - Cause: You are attempting to create a new configuration but have already +// reached the 1,000-configuration limit. +// - HTTP Error: HTTP 403 Forbidden +// - Code: AccessDenied +// - Cause: You are not the owner of the specified bucket, or you do not have +// the s3:PutAnalyticsConfiguration bucket permission to set the configuration on +// the bucket. // -// * HTTP Error: HTTP 400 Bad Request -// -// * Code: InvalidArgument -// -// * -// Cause: Invalid argument. -// -// * HTTP Error: HTTP 400 Bad Request -// -// * Code: -// TooManyConfigurations -// -// * Cause: You are attempting to create a new configuration -// but have already reached the 1,000-configuration limit. -// -// * HTTP Error: HTTP 403 -// Forbidden -// -// * Code: AccessDenied -// -// * Cause: You are not the owner of the specified -// bucket, or you do not have the s3:PutAnalyticsConfiguration bucket permission to -// set the configuration on the bucket. -// -// # Related Resources -// -// * -// GetBucketAnalyticsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAnalyticsConfiguration.html) -// -// * -// DeleteBucketAnalyticsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketAnalyticsConfiguration.html) -// -// * -// ListBucketAnalyticsConfigurations -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketAnalyticsConfigurations.html) +// The following operations are related to PutBucketAnalyticsConfiguration : +// - GetBucketAnalyticsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAnalyticsConfiguration.html) +// - DeleteBucketAnalyticsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketAnalyticsConfiguration.html) +// - ListBucketAnalyticsConfigurations (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketAnalyticsConfigurations.html) func (c *Client) PutBucketAnalyticsConfiguration(ctx context.Context, params *PutBucketAnalyticsConfigurationInput, optFns ...func(*Options)) (*PutBucketAnalyticsConfigurationOutput, error) { if params == nil { params = &PutBucketAnalyticsConfigurationInput{} @@ -132,6 +113,9 @@ func (c *Client) addOperationPutBucketAnalyticsConfigurationMiddlewares(stack *m if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -159,7 +143,7 @@ func (c *Client) addOperationPutBucketAnalyticsConfigurationMiddlewares(stack *m if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -171,6 +155,9 @@ func (c *Client) addOperationPutBucketAnalyticsConfigurationMiddlewares(stack *m if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketAnalyticsConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketAnalyticsConfigurationValidationMiddleware(stack); err != nil { return err } @@ -180,6 +167,9 @@ func (c *Client) addOperationPutBucketAnalyticsConfigurationMiddlewares(stack *m if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketAnalyticsConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -195,9 +185,22 @@ func (c *Client) addOperationPutBucketAnalyticsConfigurationMiddlewares(stack *m if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketAnalyticsConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketAnalyticsConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -232,3 +235,139 @@ func addPutBucketAnalyticsConfigurationUpdateEndpoint(stack *middleware.Stack, o DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketAnalyticsConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketAnalyticsConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketAnalyticsConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketAnalyticsConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketAnalyticsConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketAnalyticsConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketCors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketCors.go index 55a67f188..7a1f49c33 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketCors.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketCors.go @@ -4,57 +4,49 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Sets the cors configuration for your bucket. If the configuration exists, Amazon -// S3 replaces it. To use this operation, you must be allowed to perform the +// Sets the cors configuration for your bucket. If the configuration exists, +// Amazon S3 replaces it. To use this operation, you must be allowed to perform the // s3:PutBucketCORS action. By default, the bucket owner has this permission and // can grant it to others. You set this configuration on a bucket so that the // bucket can service cross-origin requests. For example, you might want to enable -// a request whose origin is http://www.example.com to access your Amazon S3 bucket -// at my.example.bucket.com by using the browser's XMLHttpRequest capability. To -// enable cross-origin resource sharing (CORS) on a bucket, you add the cors -// subresource to the bucket. The cors subresource is an XML document in which you -// configure rules that identify origins and the HTTP methods that can be executed -// on your bucket. The document is limited to 64 KB in size. When Amazon S3 -// receives a cross-origin request (or a pre-flight OPTIONS request) against a +// a request whose origin is http://www.example.com to access your Amazon S3 +// bucket at my.example.bucket.com by using the browser's XMLHttpRequest +// capability. To enable cross-origin resource sharing (CORS) on a bucket, you add +// the cors subresource to the bucket. The cors subresource is an XML document in +// which you configure rules that identify origins and the HTTP methods that can be +// executed on your bucket. The document is limited to 64 KB in size. When Amazon +// S3 receives a cross-origin request (or a pre-flight OPTIONS request) against a // bucket, it evaluates the cors configuration on the bucket and uses the first // CORSRule rule that matches the incoming browser request to enable a cross-origin // request. For a rule to match, the following conditions must be met: +// - The request's Origin header must match AllowedOrigin elements. +// - The request method (for example, GET, PUT, HEAD, and so on) or the +// Access-Control-Request-Method header in case of a pre-flight OPTIONS request +// must be one of the AllowedMethod elements. +// - Every header specified in the Access-Control-Request-Headers request header +// of a pre-flight request must match an AllowedHeader element. // -// * The -// request's Origin header must match AllowedOrigin elements. -// -// * The request method -// (for example, GET, PUT, HEAD, and so on) or the Access-Control-Request-Method -// header in case of a pre-flight OPTIONS request must be one of the AllowedMethod -// elements. -// -// * Every header specified in the Access-Control-Request-Headers -// request header of a pre-flight request must match an AllowedHeader element. -// -// For -// more information about CORS, go to Enabling Cross-Origin Resource Sharing -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html) in the Amazon S3 -// User Guide. Related Resources -// -// * GetBucketCors -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketCors.html) -// -// * -// DeleteBucketCors -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html) -// -// * -// RESTOPTIONSobject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTOPTIONSobject.html) +// For more information about CORS, go to Enabling Cross-Origin Resource Sharing (https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html) +// in the Amazon S3 User Guide. The following operations are related to +// PutBucketCors : +// - GetBucketCors (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketCors.html) +// - DeleteBucketCors (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html) +// - RESTOPTIONSobject (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTOPTIONSobject.html) func (c *Client) PutBucketCors(ctx context.Context, params *PutBucketCorsInput, optFns ...func(*Options)) (*PutBucketCorsOutput, error) { if params == nil { params = &PutBucketCorsInput{} @@ -72,15 +64,14 @@ func (c *Client) PutBucketCors(ctx context.Context, params *PutBucketCorsInput, type PutBucketCorsInput struct { - // Specifies the bucket impacted by the corsconfiguration. + // Specifies the bucket impacted by the cors configuration. // // This member is required. Bucket *string // Describes the cross-origin access configuration for objects in an Amazon S3 - // bucket. For more information, see Enabling Cross-Origin Resource Sharing - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html) in the Amazon S3 - // User Guide. + // bucket. For more information, see Enabling Cross-Origin Resource Sharing (https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html) + // in the Amazon S3 User Guide. // // This member is required. CORSConfiguration *types.CORSConfiguration @@ -89,19 +80,17 @@ type PutBucketCorsInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm - // The base64-encoded 128-bit MD5 digest of the data. This header must be used as a - // message integrity check to verify that the request body was not corrupted in - // transit. For more information, go to RFC 1864. - // (http://www.ietf.org/rfc/rfc1864.txt) For requests made using the Amazon Web - // Services Command Line Interface (CLI) or Amazon Web Services SDKs, this field is - // calculated automatically. + // The base64-encoded 128-bit MD5 digest of the data. This header must be used as + // a message integrity check to verify that the request body was not corrupted in + // transit. For more information, go to RFC 1864. (http://www.ietf.org/rfc/rfc1864.txt) + // For requests made using the Amazon Web Services Command Line Interface (CLI) or + // Amazon Web Services SDKs, this field is calculated automatically. ContentMD5 *string // The account ID of the expected bucket owner. If the bucket is owned by a @@ -128,6 +117,9 @@ func (c *Client) addOperationPutBucketCorsMiddlewares(stack *middleware.Stack, o if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -155,7 +147,7 @@ func (c *Client) addOperationPutBucketCorsMiddlewares(stack *middleware.Stack, o if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -167,6 +159,9 @@ func (c *Client) addOperationPutBucketCorsMiddlewares(stack *middleware.Stack, o if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketCorsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketCorsValidationMiddleware(stack); err != nil { return err } @@ -176,6 +171,9 @@ func (c *Client) addOperationPutBucketCorsMiddlewares(stack *middleware.Stack, o if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketCorsInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -194,9 +192,22 @@ func (c *Client) addOperationPutBucketCorsMiddlewares(stack *middleware.Stack, o if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketCorsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketCors(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -206,8 +217,8 @@ func newServiceMetadataMiddleware_opPutBucketCors(region string) *awsmiddleware. } } -// getPutBucketCorsRequestAlgorithmMember gets the request checksum algorithm value -// provided as input. +// getPutBucketCorsRequestAlgorithmMember gets the request checksum algorithm +// value provided as input. func getPutBucketCorsRequestAlgorithmMember(input interface{}) (string, bool) { in := input.(*PutBucketCorsInput) if len(in.ChecksumAlgorithm) == 0 { @@ -251,3 +262,139 @@ func addPutBucketCorsUpdateEndpoint(stack *middleware.Stack, options Options) er DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketCorsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketCorsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketCorsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketCorsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketCorsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketCorsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketEncryption.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketEncryption.go index 184f0cd31..ef1091961 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketEncryption.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketEncryption.go @@ -4,47 +4,44 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // This action uses the encryption subresource to configure default encryption and -// Amazon S3 Bucket Key for an existing bucket. Default encryption for a bucket can -// use server-side encryption with Amazon S3-managed keys (SSE-S3) or customer -// managed keys (SSE-KMS). If you specify default encryption using SSE-KMS, you can -// also configure Amazon S3 Bucket Key. When the default encryption is SSE-KMS, if -// you upload an object to the bucket and do not specify the KMS key to use for -// encryption, Amazon S3 uses the default Amazon Web Services managed KMS key for -// your account. For information about default encryption, see Amazon S3 default -// bucket encryption -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html) in the -// Amazon S3 User Guide. For more information about S3 Bucket Keys, see Amazon S3 -// Bucket Keys (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html) in -// the Amazon S3 User Guide. This action requires Amazon Web Services Signature -// Version 4. For more information, see Authenticating Requests (Amazon Web -// Services Signature Version 4) -// (https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html). -// To use this operation, you must have permissions to perform the +// Amazon S3 Bucket Keys for an existing bucket. By default, all buckets have a +// default encryption configuration that uses server-side encryption with Amazon S3 +// managed keys (SSE-S3). You can optionally configure default encryption for a +// bucket by using server-side encryption with Key Management Service (KMS) keys +// (SSE-KMS) or dual-layer server-side encryption with Amazon Web Services KMS keys +// (DSSE-KMS). If you specify default encryption by using SSE-KMS, you can also +// configure Amazon S3 Bucket Keys (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html) +// . If you use PutBucketEncryption to set your default bucket encryption (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html) +// to SSE-KMS, you should verify that your KMS key ID is correct. Amazon S3 does +// not validate the KMS key ID provided in PutBucketEncryption requests. This +// action requires Amazon Web Services Signature Version 4. For more information, +// see Authenticating Requests (Amazon Web Services Signature Version 4) (https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) +// . To use this operation, you must have permission to perform the // s3:PutEncryptionConfiguration action. The bucket owner has this permission by // default. The bucket owner can grant this permission to others. For more // information about permissions, see Permissions Related to Bucket Subresource -// Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) -// in the Amazon S3 User Guide. Related Resources -// -// * GetBucketEncryption -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html) -// -// * -// DeleteBucketEncryption -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketEncryption.html) +// Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// in the Amazon S3 User Guide. The following operations are related to +// PutBucketEncryption : +// - GetBucketEncryption (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html) +// - DeleteBucketEncryption (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketEncryption.html) func (c *Client) PutBucketEncryption(ctx context.Context, params *PutBucketEncryptionInput, optFns ...func(*Options)) (*PutBucketEncryptionOutput, error) { if params == nil { params = &PutBucketEncryptionInput{} @@ -63,11 +60,13 @@ func (c *Client) PutBucketEncryption(ctx context.Context, params *PutBucketEncry type PutBucketEncryptionInput struct { // Specifies default encryption for a bucket using server-side encryption with - // Amazon S3-managed keys (SSE-S3) or customer managed keys (SSE-KMS). For - // information about the Amazon S3 default encryption feature, see Amazon S3 - // Default Bucket Encryption - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html) in the - // Amazon S3 User Guide. + // different key options. By default, all buckets have a default encryption + // configuration that uses server-side encryption with Amazon S3 managed keys + // (SSE-S3). You can optionally configure default encryption for a bucket by using + // server-side encryption with an Amazon Web Services KMS key (SSE-KMS) or a + // customer-provided key (SSE-C). For information about the bucket default + // encryption feature, see Amazon S3 Bucket Default Encryption (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -81,9 +80,8 @@ type PutBucketEncryptionInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm @@ -118,6 +116,9 @@ func (c *Client) addOperationPutBucketEncryptionMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -145,7 +146,7 @@ func (c *Client) addOperationPutBucketEncryptionMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -157,6 +158,9 @@ func (c *Client) addOperationPutBucketEncryptionMiddlewares(stack *middleware.St if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketEncryptionResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketEncryptionValidationMiddleware(stack); err != nil { return err } @@ -166,6 +170,9 @@ func (c *Client) addOperationPutBucketEncryptionMiddlewares(stack *middleware.St if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketEncryptionInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -184,9 +191,22 @@ func (c *Client) addOperationPutBucketEncryptionMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketEncryptionInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketEncryption(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -196,8 +216,8 @@ func newServiceMetadataMiddleware_opPutBucketEncryption(region string) *awsmiddl } } -// getPutBucketEncryptionRequestAlgorithmMember gets the request checksum algorithm -// value provided as input. +// getPutBucketEncryptionRequestAlgorithmMember gets the request checksum +// algorithm value provided as input. func getPutBucketEncryptionRequestAlgorithmMember(input interface{}) (string, bool) { in := input.(*PutBucketEncryptionInput) if len(in.ChecksumAlgorithm) == 0 { @@ -241,3 +261,139 @@ func addPutBucketEncryptionUpdateEndpoint(stack *middleware.Stack, options Optio DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketEncryptionResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketEncryptionResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketEncryptionResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketEncryptionInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketEncryptionResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketEncryptionResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketIntelligentTieringConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketIntelligentTieringConfiguration.go index edf5d178b..d6725e64b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketIntelligentTieringConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketIntelligentTieringConfiguration.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -26,51 +32,22 @@ import ( // monitored and not eligible for auto-tiering. Smaller objects can be stored, but // they are always charged at the Frequent Access tier rates in the S3 // Intelligent-Tiering storage class. For more information, see Storage class for -// automatically optimizing frequently and infrequently accessed objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access). -// Operations related to PutBucketIntelligentTieringConfiguration include: +// automatically optimizing frequently and infrequently accessed objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access) +// . Operations related to PutBucketIntelligentTieringConfiguration include: +// - DeleteBucketIntelligentTieringConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketIntelligentTieringConfiguration.html) +// - GetBucketIntelligentTieringConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketIntelligentTieringConfiguration.html) +// - ListBucketIntelligentTieringConfigurations (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketIntelligentTieringConfigurations.html) // -// * -// DeleteBucketIntelligentTieringConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketIntelligentTieringConfiguration.html) -// -// * -// GetBucketIntelligentTieringConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketIntelligentTieringConfiguration.html) -// -// * -// ListBucketIntelligentTieringConfigurations -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketIntelligentTieringConfigurations.html) -// -// You -// only need S3 Intelligent-Tiering enabled on a bucket if you want to +// You only need S3 Intelligent-Tiering enabled on a bucket if you want to // automatically move objects stored in the S3 Intelligent-Tiering storage class to -// the Archive Access or Deep Archive Access tier. Special Errors -// -// * HTTP 400 Bad -// Request Error -// -// * Code: InvalidArgument -// -// * Cause: Invalid Argument -// -// * HTTP 400 -// Bad Request Error -// -// * Code: TooManyConfigurations -// -// * Cause: You are attempting to -// create a new configuration but have already reached the 1,000-configuration -// limit. -// -// * HTTP 403 Forbidden Error -// -// * Code: AccessDenied -// -// * Cause: You are not -// the owner of the specified bucket, or you do not have the -// s3:PutIntelligentTieringConfiguration bucket permission to set the configuration -// on the bucket. +// the Archive Access or Deep Archive Access tier. +// PutBucketIntelligentTieringConfiguration has the following special errors: HTTP +// 400 Bad Request Error Code: InvalidArgument Cause: Invalid Argument HTTP 400 Bad +// Request Error Code: TooManyConfigurations Cause: You are attempting to create a +// new configuration but have already reached the 1,000-configuration limit. HTTP +// 403 Forbidden Error Cause: You are not the owner of the specified bucket, or you +// do not have the s3:PutIntelligentTieringConfiguration bucket permission to set +// the configuration on the bucket. func (c *Client) PutBucketIntelligentTieringConfiguration(ctx context.Context, params *PutBucketIntelligentTieringConfigurationInput, optFns ...func(*Options)) (*PutBucketIntelligentTieringConfigurationOutput, error) { if params == nil { params = &PutBucketIntelligentTieringConfigurationInput{} @@ -123,6 +100,9 @@ func (c *Client) addOperationPutBucketIntelligentTieringConfigurationMiddlewares if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -150,7 +130,7 @@ func (c *Client) addOperationPutBucketIntelligentTieringConfigurationMiddlewares if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -162,6 +142,9 @@ func (c *Client) addOperationPutBucketIntelligentTieringConfigurationMiddlewares if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketIntelligentTieringConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketIntelligentTieringConfigurationValidationMiddleware(stack); err != nil { return err } @@ -171,6 +154,9 @@ func (c *Client) addOperationPutBucketIntelligentTieringConfigurationMiddlewares if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketIntelligentTieringConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -186,9 +172,22 @@ func (c *Client) addOperationPutBucketIntelligentTieringConfigurationMiddlewares if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketIntelligentTieringConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketIntelligentTieringConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -223,3 +222,139 @@ func addPutBucketIntelligentTieringConfigurationUpdateEndpoint(stack *middleware DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketIntelligentTieringConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketIntelligentTieringConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketIntelligentTieringConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketIntelligentTieringConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketIntelligentTieringConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketIntelligentTieringConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketInventoryConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketInventoryConfiguration.go index bb1a903b5..8c7f195d5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketInventoryConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketInventoryConfiguration.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -24,59 +30,36 @@ import ( // to be stored, and whether to generate the inventory daily or weekly. You can // also configure what object metadata to include and whether to inventory all // object versions or only current versions. For more information, see Amazon S3 -// Inventory -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html) in the -// Amazon S3 User Guide. You must create a bucket policy on the destination bucket -// to grant permissions to Amazon S3 to write objects to the bucket in the defined -// location. For an example policy, see Granting Permissions for Amazon S3 -// Inventory and Storage Class Analysis -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html#example-bucket-policies-use-case-9). -// To use this operation, you must have permissions to perform the +// Inventory (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html) +// in the Amazon S3 User Guide. You must create a bucket policy on the destination +// bucket to grant permissions to Amazon S3 to write objects to the bucket in the +// defined location. For an example policy, see Granting Permissions for Amazon S3 +// Inventory and Storage Class Analysis (https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html#example-bucket-policies-use-case-9) +// . Permissions To use this operation, you must have permission to perform the // s3:PutInventoryConfiguration action. The bucket owner has this permission by -// default and can grant this permission to others. For more information about -// permissions, see Permissions Related to Bucket Subresource Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) -// in the Amazon S3 User Guide. Special Errors -// -// * HTTP 400 Bad Request Error -// -// * -// Code: InvalidArgument -// -// * Cause: Invalid Argument -// -// * HTTP 400 Bad Request -// Error -// -// * Code: TooManyConfigurations -// -// * Cause: You are attempting to create a -// new configuration but have already reached the 1,000-configuration limit. -// -// * -// HTTP 403 Forbidden Error -// -// * Code: AccessDenied -// -// * Cause: You are not the owner +// default and can grant this permission to others. The +// s3:PutInventoryConfiguration permission allows a user to create an S3 Inventory (https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage-inventory.html) +// report that includes all object metadata fields available and to specify the +// destination bucket to store the inventory. A user with read access to objects in +// the destination bucket can also access all object metadata fields that are +// available in the inventory report. To restrict access to an inventory report, +// see Restricting access to an Amazon S3 Inventory report (https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html#example-bucket-policies-use-case-10) +// in the Amazon S3 User Guide. For more information about the metadata fields +// available in S3 Inventory, see Amazon S3 Inventory lists (https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage-inventory.html#storage-inventory-contents) +// in the Amazon S3 User Guide. For more information about permissions, see +// Permissions related to bucket subresource operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Identity and access management in Amazon S3 (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// in the Amazon S3 User Guide. PutBucketInventoryConfiguration has the following +// special errors: HTTP 400 Bad Request Error Code: InvalidArgument Cause: Invalid +// Argument HTTP 400 Bad Request Error Code: TooManyConfigurations Cause: You are +// attempting to create a new configuration but have already reached the +// 1,000-configuration limit. HTTP 403 Forbidden Error Cause: You are not the owner // of the specified bucket, or you do not have the s3:PutInventoryConfiguration -// bucket permission to set the configuration on the bucket. -// -// # Related Resources -// -// * -// GetBucketInventoryConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketInventoryConfiguration.html) -// -// * -// DeleteBucketInventoryConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketInventoryConfiguration.html) -// -// * -// ListBucketInventoryConfigurations -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketInventoryConfigurations.html) +// bucket permission to set the configuration on the bucket. The following +// operations are related to PutBucketInventoryConfiguration : +// - GetBucketInventoryConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketInventoryConfiguration.html) +// - DeleteBucketInventoryConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketInventoryConfiguration.html) +// - ListBucketInventoryConfigurations (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketInventoryConfigurations.html) func (c *Client) PutBucketInventoryConfiguration(ctx context.Context, params *PutBucketInventoryConfigurationInput, optFns ...func(*Options)) (*PutBucketInventoryConfigurationOutput, error) { if params == nil { params = &PutBucketInventoryConfigurationInput{} @@ -133,6 +116,9 @@ func (c *Client) addOperationPutBucketInventoryConfigurationMiddlewares(stack *m if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -160,7 +146,7 @@ func (c *Client) addOperationPutBucketInventoryConfigurationMiddlewares(stack *m if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -172,6 +158,9 @@ func (c *Client) addOperationPutBucketInventoryConfigurationMiddlewares(stack *m if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketInventoryConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketInventoryConfigurationValidationMiddleware(stack); err != nil { return err } @@ -181,6 +170,9 @@ func (c *Client) addOperationPutBucketInventoryConfigurationMiddlewares(stack *m if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketInventoryConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -196,9 +188,22 @@ func (c *Client) addOperationPutBucketInventoryConfigurationMiddlewares(stack *m if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketInventoryConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketInventoryConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -233,3 +238,139 @@ func addPutBucketInventoryConfigurationUpdateEndpoint(stack *middleware.Stack, o DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketInventoryConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketInventoryConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketInventoryConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketInventoryConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketInventoryConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketInventoryConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketLifecycleConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketLifecycleConfiguration.go index ca79b24e9..1cebaee58 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketLifecycleConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketLifecycleConfiguration.go @@ -4,11 +4,17 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -17,73 +23,52 @@ import ( // lifecycle configuration. Keep in mind that this will overwrite an existing // lifecycle configuration, so if you want to retain any configuration details, // they must be included in the new lifecycle configuration. For information about -// lifecycle configuration, see Managing your storage lifecycle -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html). -// Bucket lifecycle configuration now supports specifying a lifecycle rule using an -// object key name prefix, one or more object tags, or a combination of both. +// lifecycle configuration, see Managing your storage lifecycle (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html) +// . Bucket lifecycle configuration now supports specifying a lifecycle rule using +// an object key name prefix, one or more object tags, or a combination of both. // Accordingly, this section describes the latest API. The previous version of the // API supported filtering based only on an object key name prefix, which is // supported for backward compatibility. For the related API description, see -// PutBucketLifecycle -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycle.html). -// Rules You specify the lifecycle configuration in your request body. The +// PutBucketLifecycle (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycle.html) +// . Rules You specify the lifecycle configuration in your request body. The // lifecycle configuration is specified as XML consisting of one or more rules. An // Amazon S3 Lifecycle configuration can have up to 1,000 rules. This limit is not // adjustable. Each rule consists of the following: // -// * Filter identifying a subset -// of objects to which the rule applies. The filter can be based on a key name -// prefix, object tags, or a combination of both. +// - A filter identifying a subset of objects to which the rule applies. The +// filter can be based on a key name prefix, object tags, or a combination of both. // -// * Status whether the rule is in -// effect. +// - A status indicating whether the rule is in effect. // -// * One or more lifecycle transition and expiration actions that you want -// Amazon S3 to perform on the objects identified by the filter. If the state of -// your bucket is versioning-enabled or versioning-suspended, you can have many -// versions of the same object (one current version and zero or more noncurrent -// versions). Amazon S3 provides predefined actions that you can specify for -// current and noncurrent object versions. +// - One or more lifecycle transition and expiration actions that you want +// Amazon S3 to perform on the objects identified by the filter. If the state of +// your bucket is versioning-enabled or versioning-suspended, you can have many +// versions of the same object (one current version and zero or more noncurrent +// versions). Amazon S3 provides predefined actions that you can specify for +// current and noncurrent object versions. // -// For more information, see Object -// Lifecycle Management -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html) and -// Lifecycle Configuration Elements -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html). -// Permissions By default, all Amazon S3 resources are private, including buckets, -// objects, and related subresources (for example, lifecycle configuration and -// website configuration). Only the resource owner (that is, the Amazon Web +// For more information, see Object Lifecycle Management (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html) +// and Lifecycle Configuration Elements (https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html) +// . Permissions By default, all Amazon S3 resources are private, including +// buckets, objects, and related subresources (for example, lifecycle configuration +// and website configuration). Only the resource owner (that is, the Amazon Web // Services account that created it) can access the resource. The resource owner // can optionally grant access permissions to others by writing an access policy. -// For this operation, a user must get the s3:PutLifecycleConfiguration permission. -// You can also explicitly deny permissions. Explicit deny also supersedes any -// other permissions. If you want to block users or accounts from removing or -// deleting objects from your bucket, you must deny them permissions for the -// following actions: +// For this operation, a user must get the s3:PutLifecycleConfiguration +// permission. You can also explicitly deny permissions. An explicit deny also +// supersedes any other permissions. If you want to block users or accounts from +// removing or deleting objects from your bucket, you must deny them permissions +// for the following actions: +// - s3:DeleteObject +// - s3:DeleteObjectVersion +// - s3:PutLifecycleConfiguration // -// * s3:DeleteObject -// -// * s3:DeleteObjectVersion -// -// * -// s3:PutLifecycleConfiguration -// -// For more information about permissions, see -// Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// The following are related to PutBucketLifecycleConfiguration: -// -// * Examples of -// Lifecycle Configuration -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/lifecycle-configuration-examples.html) -// -// * -// GetBucketLifecycleConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html) -// -// * -// DeleteBucketLifecycle -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketLifecycle.html) +// For more information about permissions, see Managing Access Permissions to Your +// Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . The following operations are related to PutBucketLifecycleConfiguration : +// - Examples of Lifecycle Configuration (https://docs.aws.amazon.com/AmazonS3/latest/dev/lifecycle-configuration-examples.html) +// - GetBucketLifecycleConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html) +// - DeleteBucketLifecycle (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketLifecycle.html) func (c *Client) PutBucketLifecycleConfiguration(ctx context.Context, params *PutBucketLifecycleConfigurationInput, optFns ...func(*Options)) (*PutBucketLifecycleConfigurationOutput, error) { if params == nil { params = &PutBucketLifecycleConfigurationInput{} @@ -110,9 +95,8 @@ type PutBucketLifecycleConfigurationInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm @@ -144,6 +128,9 @@ func (c *Client) addOperationPutBucketLifecycleConfigurationMiddlewares(stack *m if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -171,7 +158,7 @@ func (c *Client) addOperationPutBucketLifecycleConfigurationMiddlewares(stack *m if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -183,6 +170,9 @@ func (c *Client) addOperationPutBucketLifecycleConfigurationMiddlewares(stack *m if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketLifecycleConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketLifecycleConfigurationValidationMiddleware(stack); err != nil { return err } @@ -192,6 +182,9 @@ func (c *Client) addOperationPutBucketLifecycleConfigurationMiddlewares(stack *m if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketLifecycleConfigurationInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -210,9 +203,22 @@ func (c *Client) addOperationPutBucketLifecycleConfigurationMiddlewares(stack *m if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketLifecycleConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketLifecycleConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -267,3 +273,139 @@ func addPutBucketLifecycleConfigurationUpdateEndpoint(stack *middleware.Stack, o DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketLifecycleConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketLifecycleConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketLifecycleConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketLifecycleConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketLifecycleConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketLifecycleConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketLogging.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketLogging.go index 0f3ea6d33..456288247 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketLogging.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketLogging.go @@ -4,11 +4,17 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -23,49 +29,29 @@ import ( // the bucket owner enforced setting for S3 Object Ownership, you can't use the // Grantee request element to grant access to others. Permissions can only be // granted using policies. For more information, see Permissions for server access -// log delivery -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html#grant-log-delivery-permissions-general) +// log delivery (https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html#grant-log-delivery-permissions-general) // in the Amazon S3 User Guide. Grantee Values You can specify the person (grantee) -// to whom you're assigning access rights (using request elements) in the following -// ways: +// to whom you're assigning access rights (by using request elements) in the +// following ways: +// - By the person's ID: <>ID<><>GranteesEmail<> DisplayName is optional and +// ignored in the request. +// - By Email address: <>Grantees@email.com<> The grantee is resolved to the +// CanonicalUser and, in a response to a GETObjectAcl request, appears as the +// CanonicalUser. +// - By URI: <>http://acs.amazonaws.com/groups/global/AuthenticatedUsers<> // -// * By the person's ID: <>ID<><>GranteesEmail<> DisplayName is optional -// and ignored in the request. -// -// * By Email address: <>Grantees@email.com<> The -// grantee is resolved to the CanonicalUser and, in a response to a GET Object acl -// request, appears as the CanonicalUser. -// -// * By URI: -// <>http://acs.amazonaws.com/groups/global/AuthenticatedUsers<> -// -// To enable -// logging, you use LoggingEnabled and its children request elements. To disable -// logging, you use an empty BucketLoggingStatus request element: For more -// information about server access logging, see Server Access Logging -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerLogs.html) in the -// Amazon S3 User Guide. For more information about creating a bucket, see -// CreateBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html). For -// more information about returning the logging status of a bucket, see -// GetBucketLogging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLogging.html). The -// following operations are related to PutBucketLogging: -// -// * PutObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) -// -// * -// DeleteBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) -// -// * -// CreateBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) -// -// * -// GetBucketLogging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLogging.html) +// To enable logging, you use LoggingEnabled and its children request elements. To +// disable logging, you use an empty BucketLoggingStatus request element: For +// more information about server access logging, see Server Access Logging (https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerLogs.html) +// in the Amazon S3 User Guide. For more information about creating a bucket, see +// CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) +// . For more information about returning the logging status of a bucket, see +// GetBucketLogging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLogging.html) +// . The following operations are related to PutBucketLogging : +// - PutObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) +// - DeleteBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) +// - CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) +// - GetBucketLogging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLogging.html) func (c *Client) PutBucketLogging(ctx context.Context, params *PutBucketLoggingInput, optFns ...func(*Options)) (*PutBucketLoggingOutput, error) { if params == nil { params = &PutBucketLoggingInput{} @@ -97,9 +83,8 @@ type PutBucketLoggingInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm @@ -133,6 +118,9 @@ func (c *Client) addOperationPutBucketLoggingMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -160,7 +148,7 @@ func (c *Client) addOperationPutBucketLoggingMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -172,6 +160,9 @@ func (c *Client) addOperationPutBucketLoggingMiddlewares(stack *middleware.Stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketLoggingResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketLoggingValidationMiddleware(stack); err != nil { return err } @@ -181,6 +172,9 @@ func (c *Client) addOperationPutBucketLoggingMiddlewares(stack *middleware.Stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketLoggingInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -199,9 +193,22 @@ func (c *Client) addOperationPutBucketLoggingMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketLoggingInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketLogging(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -256,3 +263,139 @@ func addPutBucketLoggingUpdateEndpoint(stack *middleware.Stack, options Options) DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketLoggingResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketLoggingResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketLoggingResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketLoggingInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketLoggingResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketLoggingResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketMetricsConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketMetricsConfiguration.go index 6f0c6facd..785a1f831 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketMetricsConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketMetricsConfiguration.go @@ -4,53 +4,42 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Sets a metrics configuration (specified by the metrics configuration ID) for the -// bucket. You can have up to 1,000 metrics configurations per bucket. If you're -// updating an existing metrics configuration, note that this is a full replacement -// of the existing metrics configuration. If you don't include the elements you -// want to keep, they are erased. To use this operation, you must have permissions -// to perform the s3:PutMetricsConfiguration action. The bucket owner has this -// permission by default. The bucket owner can grant this permission to others. For -// more information about permissions, see Permissions Related to Bucket -// Subresource Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// For information about CloudWatch request metrics for Amazon S3, see Monitoring -// Metrics with Amazon CloudWatch -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html). -// The following operations are related to PutBucketMetricsConfiguration: +// Sets a metrics configuration (specified by the metrics configuration ID) for +// the bucket. You can have up to 1,000 metrics configurations per bucket. If +// you're updating an existing metrics configuration, note that this is a full +// replacement of the existing metrics configuration. If you don't include the +// elements you want to keep, they are erased. To use this operation, you must have +// permissions to perform the s3:PutMetricsConfiguration action. The bucket owner +// has this permission by default. The bucket owner can grant this permission to +// others. For more information about permissions, see Permissions Related to +// Bucket Subresource Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . For information about CloudWatch request metrics for Amazon S3, see +// Monitoring Metrics with Amazon CloudWatch (https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html) +// . The following operations are related to PutBucketMetricsConfiguration : +// - DeleteBucketMetricsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html) +// - GetBucketMetricsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html) +// - ListBucketMetricsConfigurations (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html) // -// * -// DeleteBucketMetricsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html) -// -// * -// GetBucketMetricsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html) -// -// * -// ListBucketMetricsConfigurations -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html) -// -// GetBucketLifecycle -// has the following special error: -// -// * Error code: TooManyConfigurations -// -// * -// Description: You are attempting to create a new configuration but have already -// reached the 1,000-configuration limit. -// -// * HTTP Status Code: HTTP 400 Bad Request +// PutBucketMetricsConfiguration has the following special error: +// - Error code: TooManyConfigurations +// - Description: You are attempting to create a new configuration but have +// already reached the 1,000-configuration limit. +// - HTTP Status Code: HTTP 400 Bad Request func (c *Client) PutBucketMetricsConfiguration(ctx context.Context, params *PutBucketMetricsConfigurationInput, optFns ...func(*Options)) (*PutBucketMetricsConfigurationOutput, error) { if params == nil { params = &PutBucketMetricsConfigurationInput{} @@ -73,7 +62,8 @@ type PutBucketMetricsConfigurationInput struct { // This member is required. Bucket *string - // The ID used to identify the metrics configuration. + // The ID used to identify the metrics configuration. The ID has a 64 character + // limit and can only contain letters, numbers, periods, dashes, and underscores. // // This member is required. Id *string @@ -107,6 +97,9 @@ func (c *Client) addOperationPutBucketMetricsConfigurationMiddlewares(stack *mid if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -134,7 +127,7 @@ func (c *Client) addOperationPutBucketMetricsConfigurationMiddlewares(stack *mid if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -146,6 +139,9 @@ func (c *Client) addOperationPutBucketMetricsConfigurationMiddlewares(stack *mid if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketMetricsConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketMetricsConfigurationValidationMiddleware(stack); err != nil { return err } @@ -155,6 +151,9 @@ func (c *Client) addOperationPutBucketMetricsConfigurationMiddlewares(stack *mid if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketMetricsConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -170,9 +169,22 @@ func (c *Client) addOperationPutBucketMetricsConfigurationMiddlewares(stack *mid if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketMetricsConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketMetricsConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -207,3 +219,139 @@ func addPutBucketMetricsConfigurationUpdateEndpoint(stack *middleware.Stack, opt DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketMetricsConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketMetricsConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketMetricsConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketMetricsConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketMetricsConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketMetricsConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketNotificationConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketNotificationConfiguration.go index 8e771d6bc..098445cf4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketNotificationConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketNotificationConfiguration.go @@ -4,53 +4,54 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Enables notifications of specified events for a bucket. For more information -// about event notifications, see Configuring Event Notifications -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html). Using -// this API, you can replace an existing notification configuration. The +// about event notifications, see Configuring Event Notifications (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) +// . Using this API, you can replace an existing notification configuration. The // configuration is an XML file that defines the event types that you want Amazon // S3 to publish and the destination where you want Amazon S3 to publish an event // notification when it detects an event of the specified type. By default, your // bucket has no event notifications configured. That is, the notification -// configuration will be an empty NotificationConfiguration. This action replaces -// the existing notification configuration with the configuration you include in -// the request body. After Amazon S3 receives this request, it first verifies that -// any Amazon Simple Notification Service (Amazon SNS) or Amazon Simple Queue -// Service (Amazon SQS) destination exists, and that the bucket owner has -// permission to publish to it by sending a test notification. In the case of +// configuration will be an empty NotificationConfiguration . This action +// replaces the existing notification configuration with the configuration you +// include in the request body. After Amazon S3 receives this request, it first +// verifies that any Amazon Simple Notification Service (Amazon SNS) or Amazon +// Simple Queue Service (Amazon SQS) destination exists, and that the bucket owner +// has permission to publish to it by sending a test notification. In the case of // Lambda destinations, Amazon S3 verifies that the Lambda function permissions // grant Amazon S3 permission to invoke the function from the Amazon S3 bucket. For -// more information, see Configuring Notifications for Amazon S3 Events -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html). You -// can disable notifications by adding the empty NotificationConfiguration element. -// For more information about the number of event notification configurations that -// you can create per bucket, see Amazon S3 service quotas -// (https://docs.aws.amazon.com/general/latest/gr/s3.html#limits_s3) in Amazon Web -// Services General Reference. By default, only the bucket owner can configure -// notifications on a bucket. However, bucket owners can use a bucket policy to -// grant permission to other users to set this configuration with -// s3:PutBucketNotification permission. The PUT notification is an atomic +// more information, see Configuring Notifications for Amazon S3 Events (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) +// . You can disable notifications by adding the empty NotificationConfiguration +// element. For more information about the number of event notification +// configurations that you can create per bucket, see Amazon S3 service quotas (https://docs.aws.amazon.com/general/latest/gr/s3.html#limits_s3) +// in Amazon Web Services General Reference. By default, only the bucket owner can +// configure notifications on a bucket. However, bucket owners can use a bucket +// policy to grant permission to other users to set this configuration with the +// required s3:PutBucketNotification permission. The PUT notification is an atomic // operation. For example, suppose your notification configuration includes SNS // topic, SQS queue, and Lambda function configurations. When you send a PUT // request with this configuration, Amazon S3 sends test messages to your SNS // topic. If the message fails, the entire PUT action will fail, and Amazon S3 will -// not add the configuration to your bucket. Responses If the configuration in the -// request body includes only one TopicConfiguration specifying only the +// not add the configuration to your bucket. If the configuration in the request +// body includes only one TopicConfiguration specifying only the // s3:ReducedRedundancyLostObject event type, the response will also include the // x-amz-sns-test-message-id header containing the message ID of the test // notification sent to the topic. The following action is related to -// PutBucketNotificationConfiguration: -// -// * GetBucketNotificationConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketNotificationConfiguration.html) +// PutBucketNotificationConfiguration : +// - GetBucketNotificationConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketNotificationConfiguration.html) func (c *Client) PutBucketNotificationConfiguration(ctx context.Context, params *PutBucketNotificationConfigurationInput, optFns ...func(*Options)) (*PutBucketNotificationConfigurationOutput, error) { if params == nil { params = &PutBucketNotificationConfigurationInput{} @@ -73,8 +74,8 @@ type PutBucketNotificationConfigurationInput struct { // This member is required. Bucket *string - // A container for specifying the notification configuration of the bucket. If this - // element is empty, notifications are turned off for the bucket. + // A container for specifying the notification configuration of the bucket. If + // this element is empty, notifications are turned off for the bucket. // // This member is required. NotificationConfiguration *types.NotificationConfiguration @@ -107,6 +108,9 @@ func (c *Client) addOperationPutBucketNotificationConfigurationMiddlewares(stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -134,7 +138,7 @@ func (c *Client) addOperationPutBucketNotificationConfigurationMiddlewares(stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -146,6 +150,9 @@ func (c *Client) addOperationPutBucketNotificationConfigurationMiddlewares(stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketNotificationConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketNotificationConfigurationValidationMiddleware(stack); err != nil { return err } @@ -155,6 +162,9 @@ func (c *Client) addOperationPutBucketNotificationConfigurationMiddlewares(stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketNotificationConfigurationUpdateEndpoint(stack, options); err != nil { return err } @@ -170,9 +180,22 @@ func (c *Client) addOperationPutBucketNotificationConfigurationMiddlewares(stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketNotificationConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketNotificationConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -207,3 +230,139 @@ func addPutBucketNotificationConfigurationUpdateEndpoint(stack *middleware.Stack DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketNotificationConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketNotificationConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketNotificationConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketNotificationConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketNotificationConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketNotificationConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketOwnershipControls.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketOwnershipControls.go index 83210cac4..6944f1b8b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketOwnershipControls.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketOwnershipControls.go @@ -4,27 +4,28 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Creates or modifies OwnershipControls for an Amazon S3 bucket. To use this // operation, you must have the s3:PutBucketOwnershipControls permission. For more -// information about Amazon S3 permissions, see Specifying permissions in a policy -// (https://docs.aws.amazon.com/AmazonS3/latest/user-guide/using-with-s3-actions.html). -// For information about Amazon S3 Object Ownership, see Using object ownership -// (https://docs.aws.amazon.com/AmazonS3/latest/user-guide/about-object-ownership.html). -// The following operations are related to PutBucketOwnershipControls: -// -// * -// GetBucketOwnershipControls -// -// * DeleteBucketOwnershipControls +// information about Amazon S3 permissions, see Specifying permissions in a policy (https://docs.aws.amazon.com/AmazonS3/latest/user-guide/using-with-s3-actions.html) +// . For information about Amazon S3 Object Ownership, see Using object ownership (https://docs.aws.amazon.com/AmazonS3/latest/user-guide/about-object-ownership.html) +// . The following operations are related to PutBucketOwnershipControls : +// - GetBucketOwnershipControls +// - DeleteBucketOwnershipControls func (c *Client) PutBucketOwnershipControls(ctx context.Context, params *PutBucketOwnershipControlsInput, optFns ...func(*Options)) (*PutBucketOwnershipControlsOutput, error) { if params == nil { params = &PutBucketOwnershipControlsInput{} @@ -82,6 +83,9 @@ func (c *Client) addOperationPutBucketOwnershipControlsMiddlewares(stack *middle if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -109,7 +113,7 @@ func (c *Client) addOperationPutBucketOwnershipControlsMiddlewares(stack *middle if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -121,6 +125,9 @@ func (c *Client) addOperationPutBucketOwnershipControlsMiddlewares(stack *middle if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketOwnershipControlsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketOwnershipControlsValidationMiddleware(stack); err != nil { return err } @@ -130,6 +137,9 @@ func (c *Client) addOperationPutBucketOwnershipControlsMiddlewares(stack *middle if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketOwnershipControlsInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -148,9 +158,22 @@ func (c *Client) addOperationPutBucketOwnershipControlsMiddlewares(stack *middle if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketOwnershipControlsInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketOwnershipControls(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -170,9 +193,9 @@ func addPutBucketOwnershipControlsInputChecksumMiddlewares(stack *middleware.Sta }) } -// getPutBucketOwnershipControlsBucketMember returns a pointer to string denoting a -// provided bucket member valueand a boolean indicating if the input has a modeled -// bucket name, +// getPutBucketOwnershipControlsBucketMember returns a pointer to string denoting +// a provided bucket member valueand a boolean indicating if the input has a +// modeled bucket name, func getPutBucketOwnershipControlsBucketMember(input interface{}) (*string, bool) { in := input.(*PutBucketOwnershipControlsInput) if in.Bucket == nil { @@ -195,3 +218,139 @@ func addPutBucketOwnershipControlsUpdateEndpoint(stack *middleware.Stack, option DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketOwnershipControlsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketOwnershipControlsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketOwnershipControlsResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketOwnershipControlsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketOwnershipControlsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketOwnershipControlsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketPolicy.go index 8860d3b56..999c38a7b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketPolicy.go @@ -4,11 +4,17 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -17,22 +23,20 @@ import ( // identity other than the root user of the Amazon Web Services account that owns // the bucket, the calling identity must have the PutBucketPolicy permissions on // the specified bucket and belong to the bucket owner's account in order to use -// this operation. If you don't have PutBucketPolicy permissions, Amazon S3 returns -// a 403 Access Denied error. If you have the correct permissions, but you're not -// using an identity that belongs to the bucket owner's account, Amazon S3 returns -// a 405 Method Not Allowed error. As a security precaution, the root user of the -// Amazon Web Services account that owns a bucket can always use this operation, -// even if the policy explicitly denies the root user the ability to perform this -// action. For more information, see Bucket policy examples -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html). -// The following operations are related to PutBucketPolicy: -// -// * CreateBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) -// -// * -// DeleteBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) +// this operation. If you don't have PutBucketPolicy permissions, Amazon S3 +// returns a 403 Access Denied error. If you have the correct permissions, but +// you're not using an identity that belongs to the bucket owner's account, Amazon +// S3 returns a 405 Method Not Allowed error. To ensure that bucket owners don't +// inadvertently lock themselves out of their own buckets, the root principal in a +// bucket owner's Amazon Web Services account can perform the GetBucketPolicy , +// PutBucketPolicy , and DeleteBucketPolicy API actions, even if their bucket +// policy explicitly denies the root principal's access. Bucket owner root +// principals can only be blocked from performing these API actions by VPC endpoint +// policies and Amazon Web Services Organizations policies. For more information, +// see Bucket policy examples (https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html) +// . The following operations are related to PutBucketPolicy : +// - CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) +// - DeleteBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) func (c *Client) PutBucketPolicy(ctx context.Context, params *PutBucketPolicyInput, optFns ...func(*Options)) (*PutBucketPolicyOutput, error) { if params == nil { params = &PutBucketPolicyInput{} @@ -64,9 +68,8 @@ type PutBucketPolicyInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm @@ -104,6 +107,9 @@ func (c *Client) addOperationPutBucketPolicyMiddlewares(stack *middleware.Stack, if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -131,7 +137,7 @@ func (c *Client) addOperationPutBucketPolicyMiddlewares(stack *middleware.Stack, if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -143,6 +149,9 @@ func (c *Client) addOperationPutBucketPolicyMiddlewares(stack *middleware.Stack, if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketPolicyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketPolicyValidationMiddleware(stack); err != nil { return err } @@ -152,6 +161,9 @@ func (c *Client) addOperationPutBucketPolicyMiddlewares(stack *middleware.Stack, if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketPolicyInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -170,9 +182,22 @@ func (c *Client) addOperationPutBucketPolicyMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketPolicyInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketPolicy(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -227,3 +252,139 @@ func addPutBucketPolicyUpdateEndpoint(stack *middleware.Stack, options Options) DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketPolicyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketPolicyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketPolicyResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketPolicyInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketPolicyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketPolicyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketReplication.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketReplication.go index 2213373f3..d44e96bc8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketReplication.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketReplication.go @@ -4,67 +4,62 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Creates a replication configuration or replaces an existing one. For more -// information, see Replication -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication.html) in the Amazon -// S3 User Guide. Specify the replication configuration in the request body. In the -// replication configuration, you provide the name of the destination bucket or -// buckets where you want Amazon S3 to replicate objects, the IAM role that Amazon -// S3 can assume to replicate objects on your behalf, and other relevant -// information. A replication configuration must include at least one rule, and can -// contain a maximum of 1,000. Each rule identifies a subset of objects to +// information, see Replication (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication.html) +// in the Amazon S3 User Guide. Specify the replication configuration in the +// request body. In the replication configuration, you provide the name of the +// destination bucket or buckets where you want Amazon S3 to replicate objects, the +// IAM role that Amazon S3 can assume to replicate objects on your behalf, and +// other relevant information. You can invoke this request for a specific Amazon +// Web Services Region by using the aws:RequestedRegion (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requestedregion) +// condition key. A replication configuration must include at least one rule, and +// can contain a maximum of 1,000. Each rule identifies a subset of objects to // replicate by filtering the objects in the source bucket. To choose additional // subsets of objects to replicate, add a rule for each subset. To specify a subset // of the objects in the source bucket to apply a replication rule to, add the // Filter element as a child of the Rule element. You can filter objects based on // an object key prefix, one or more object tags, or both. When you add the Filter // element in the configuration, you must also add the following elements: -// DeleteMarkerReplication, Status, and Priority. If you are using an earlier +// DeleteMarkerReplication , Status , and Priority . If you are using an earlier // version of the replication configuration, Amazon S3 handles replication of -// delete markers differently. For more information, see Backward Compatibility -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-add-config.html#replication-backward-compat-considerations). -// For information about enabling versioning on a bucket, see Using Versioning -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html). Handling -// Replication of Encrypted Objects By default, Amazon S3 doesn't replicate objects -// that are stored at rest using server-side encryption with KMS keys. To replicate -// Amazon Web Services KMS-encrypted objects, add the following: -// SourceSelectionCriteria, SseKmsEncryptedObjects, Status, -// EncryptionConfiguration, and ReplicaKmsKeyID. For information about replication -// configuration, see Replicating Objects Created with SSE Using KMS keys -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-config-for-kms-objects.html). -// For information on PutBucketReplication errors, see List of replication-related -// error codes -// (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ReplicationErrorCodeList) +// delete markers differently. For more information, see Backward Compatibility (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-add-config.html#replication-backward-compat-considerations) +// . For information about enabling versioning on a bucket, see Using Versioning (https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html) +// . Handling Replication of Encrypted Objects By default, Amazon S3 doesn't +// replicate objects that are stored at rest using server-side encryption with KMS +// keys. To replicate Amazon Web Services KMS-encrypted objects, add the following: +// SourceSelectionCriteria , SseKmsEncryptedObjects , Status , +// EncryptionConfiguration , and ReplicaKmsKeyID . For information about +// replication configuration, see Replicating Objects Created with SSE Using KMS +// keys (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-config-for-kms-objects.html) +// . For information on PutBucketReplication errors, see List of +// replication-related error codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ReplicationErrorCodeList) // Permissions To create a PutBucketReplication request, you must have // s3:PutReplicationConfiguration permissions for the bucket. By default, a // resource owner, in this case the Amazon Web Services account that created the // bucket, can perform this operation. The resource owner can also grant others // permissions to perform the operation. For more information about permissions, -// see Specifying Permissions in a Policy -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html) and -// Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// To perform this operation, the user or role performing the action must have the -// iam:PassRole -// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_passrole.html) -// permission. The following operations are related to PutBucketReplication: -// -// * -// GetBucketReplication -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketReplication.html) -// -// * -// DeleteBucketReplication -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketReplication.html) +// see Specifying Permissions in a Policy (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . To perform this operation, the user or role performing the action must have +// the iam:PassRole (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_passrole.html) +// permission. The following operations are related to PutBucketReplication : +// - GetBucketReplication (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketReplication.html) +// - DeleteBucketReplication (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketReplication.html) func (c *Client) PutBucketReplication(ctx context.Context, params *PutBucketReplicationInput, optFns ...func(*Options)) (*PutBucketReplicationOutput, error) { if params == nil { params = &PutBucketReplicationInput{} @@ -97,19 +92,17 @@ type PutBucketReplicationInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm - // The base64-encoded 128-bit MD5 digest of the data. You must use this header as a - // message integrity check to verify that the request body was not corrupted in - // transit. For more information, see RFC 1864 - // (http://www.ietf.org/rfc/rfc1864.txt). For requests made using the Amazon Web - // Services Command Line Interface (CLI) or Amazon Web Services SDKs, this field is - // calculated automatically. + // The base64-encoded 128-bit MD5 digest of the data. You must use this header as + // a message integrity check to verify that the request body was not corrupted in + // transit. For more information, see RFC 1864 (http://www.ietf.org/rfc/rfc1864.txt) + // . For requests made using the Amazon Web Services Command Line Interface (CLI) + // or Amazon Web Services SDKs, this field is calculated automatically. ContentMD5 *string // The account ID of the expected bucket owner. If the bucket is owned by a @@ -139,6 +132,9 @@ func (c *Client) addOperationPutBucketReplicationMiddlewares(stack *middleware.S if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -166,7 +162,7 @@ func (c *Client) addOperationPutBucketReplicationMiddlewares(stack *middleware.S if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -178,6 +174,9 @@ func (c *Client) addOperationPutBucketReplicationMiddlewares(stack *middleware.S if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketReplicationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketReplicationValidationMiddleware(stack); err != nil { return err } @@ -187,6 +186,9 @@ func (c *Client) addOperationPutBucketReplicationMiddlewares(stack *middleware.S if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketReplicationInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -205,9 +207,22 @@ func (c *Client) addOperationPutBucketReplicationMiddlewares(stack *middleware.S if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketReplicationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketReplication(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -262,3 +277,139 @@ func addPutBucketReplicationUpdateEndpoint(stack *middleware.Stack, options Opti DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketReplicationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketReplicationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketReplicationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketReplicationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketReplicationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketReplicationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketRequestPayment.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketRequestPayment.go index c89d97bec..427b7b103 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketRequestPayment.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketRequestPayment.go @@ -4,11 +4,17 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -16,16 +22,10 @@ import ( // Sets the request payment configuration for a bucket. By default, the bucket // owner pays for downloads from the bucket. This configuration parameter enables // the bucket owner (only) to specify that the person requesting the download will -// be charged for the download. For more information, see Requester Pays Buckets -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/RequesterPaysBuckets.html). The -// following operations are related to PutBucketRequestPayment: -// -// * CreateBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) -// -// * -// GetBucketRequestPayment -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketRequestPayment.html) +// be charged for the download. For more information, see Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/RequesterPaysBuckets.html) +// . The following operations are related to PutBucketRequestPayment : +// - CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) +// - GetBucketRequestPayment (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketRequestPayment.html) func (c *Client) PutBucketRequestPayment(ctx context.Context, params *PutBucketRequestPaymentInput, optFns ...func(*Options)) (*PutBucketRequestPaymentOutput, error) { if params == nil { params = &PutBucketRequestPaymentInput{} @@ -57,19 +57,17 @@ type PutBucketRequestPaymentInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm - // The base64-encoded 128-bit MD5 digest of the data. You must use this header as a - // message integrity check to verify that the request body was not corrupted in - // transit. For more information, see RFC 1864 - // (http://www.ietf.org/rfc/rfc1864.txt). For requests made using the Amazon Web - // Services Command Line Interface (CLI) or Amazon Web Services SDKs, this field is - // calculated automatically. + // The base64-encoded 128-bit MD5 digest of the data. You must use this header as + // a message integrity check to verify that the request body was not corrupted in + // transit. For more information, see RFC 1864 (http://www.ietf.org/rfc/rfc1864.txt) + // . For requests made using the Amazon Web Services Command Line Interface (CLI) + // or Amazon Web Services SDKs, this field is calculated automatically. ContentMD5 *string // The account ID of the expected bucket owner. If the bucket is owned by a @@ -96,6 +94,9 @@ func (c *Client) addOperationPutBucketRequestPaymentMiddlewares(stack *middlewar if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -123,7 +124,7 @@ func (c *Client) addOperationPutBucketRequestPaymentMiddlewares(stack *middlewar if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -135,6 +136,9 @@ func (c *Client) addOperationPutBucketRequestPaymentMiddlewares(stack *middlewar if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketRequestPaymentResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketRequestPaymentValidationMiddleware(stack); err != nil { return err } @@ -144,6 +148,9 @@ func (c *Client) addOperationPutBucketRequestPaymentMiddlewares(stack *middlewar if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketRequestPaymentInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -162,9 +169,22 @@ func (c *Client) addOperationPutBucketRequestPaymentMiddlewares(stack *middlewar if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketRequestPaymentInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketRequestPayment(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -219,3 +239,139 @@ func addPutBucketRequestPaymentUpdateEndpoint(stack *middleware.Stack, options O DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketRequestPaymentResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketRequestPaymentResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketRequestPaymentResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketRequestPaymentInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketRequestPaymentResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketRequestPaymentResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketTagging.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketTagging.go index f41010773..9792ad38e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketTagging.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketTagging.go @@ -4,11 +4,17 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -20,57 +26,31 @@ import ( // with the same tag key values. For example, you can tag several resources with a // specific application name, and then organize your billing information to see the // total cost of that application across several services. For more information, -// see Cost Allocation and Tagging -// (https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html) -// and Using Cost Allocation in Amazon S3 Bucket Tags -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/CostAllocTagging.html). When -// this operation sets the tags for a bucket, it will overwrite any current tags -// the bucket already has. You cannot use this operation to add tags to an existing -// list of tags. To use this operation, you must have permissions to perform the -// s3:PutBucketTagging action. The bucket owner has this permission by default and -// can grant this permission to others. For more information about permissions, see -// Permissions Related to Bucket Subresource Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). -// PutBucketTagging has the following special errors: +// see Cost Allocation and Tagging (https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html) +// and Using Cost Allocation in Amazon S3 Bucket Tags (https://docs.aws.amazon.com/AmazonS3/latest/userguide/CostAllocTagging.html) +// . When this operation sets the tags for a bucket, it will overwrite any current +// tags the bucket already has. You cannot use this operation to add tags to an +// existing list of tags. To use this operation, you must have permissions to +// perform the s3:PutBucketTagging action. The bucket owner has this permission by +// default and can grant this permission to others. For more information about +// permissions, see Permissions Related to Bucket Subresource Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// . PutBucketTagging has the following special errors. For more Amazon S3 errors +// see, Error Responses (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html) +// . +// - InvalidTag - The tag provided was not a valid tag. This error can occur if +// the tag did not pass input validation. For more information, see Using Cost +// Allocation in Amazon S3 Bucket Tags (https://docs.aws.amazon.com/AmazonS3/latest/userguide/CostAllocTagging.html) +// . +// - MalformedXML - The XML provided does not match the schema. +// - OperationAborted - A conflicting conditional action is currently in progress +// against this resource. Please try again. +// - InternalError - The service was unable to apply the provided tag to the +// bucket. // -// * Error code: -// InvalidTagError -// -// * Description: The tag provided was not a valid tag. This error -// can occur if the tag did not pass input validation. For information about tag -// restrictions, see User-Defined Tag Restrictions -// (https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/allocation-tag-restrictions.html) -// and Amazon Web Services-Generated Cost Allocation Tag Restrictions -// (https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/aws-tag-restrictions.html). -// -// * -// Error code: MalformedXMLError -// -// * Description: The XML provided does not match -// the schema. -// -// * Error code: OperationAbortedError -// -// * Description: A conflicting -// conditional action is currently in progress against this resource. Please try -// again. -// -// * Error code: InternalError -// -// * Description: The service was unable to -// apply the provided tag to the bucket. -// -// The following operations are related to -// PutBucketTagging: -// -// * GetBucketTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketTagging.html) -// -// * -// DeleteBucketTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketTagging.html) +// The following operations are related to PutBucketTagging : +// - GetBucketTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketTagging.html) +// - DeleteBucketTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketTagging.html) func (c *Client) PutBucketTagging(ctx context.Context, params *PutBucketTaggingInput, optFns ...func(*Options)) (*PutBucketTaggingOutput, error) { if params == nil { params = &PutBucketTaggingInput{} @@ -102,19 +82,17 @@ type PutBucketTaggingInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm - // The base64-encoded 128-bit MD5 digest of the data. You must use this header as a - // message integrity check to verify that the request body was not corrupted in - // transit. For more information, see RFC 1864 - // (http://www.ietf.org/rfc/rfc1864.txt). For requests made using the Amazon Web - // Services Command Line Interface (CLI) or Amazon Web Services SDKs, this field is - // calculated automatically. + // The base64-encoded 128-bit MD5 digest of the data. You must use this header as + // a message integrity check to verify that the request body was not corrupted in + // transit. For more information, see RFC 1864 (http://www.ietf.org/rfc/rfc1864.txt) + // . For requests made using the Amazon Web Services Command Line Interface (CLI) + // or Amazon Web Services SDKs, this field is calculated automatically. ContentMD5 *string // The account ID of the expected bucket owner. If the bucket is owned by a @@ -141,6 +119,9 @@ func (c *Client) addOperationPutBucketTaggingMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -168,7 +149,7 @@ func (c *Client) addOperationPutBucketTaggingMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -180,6 +161,9 @@ func (c *Client) addOperationPutBucketTaggingMiddlewares(stack *middleware.Stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketTaggingResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketTaggingValidationMiddleware(stack); err != nil { return err } @@ -189,6 +173,9 @@ func (c *Client) addOperationPutBucketTaggingMiddlewares(stack *middleware.Stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketTaggingInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -207,9 +194,22 @@ func (c *Client) addOperationPutBucketTaggingMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketTaggingInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketTagging(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -264,3 +264,139 @@ func addPutBucketTaggingUpdateEndpoint(stack *middleware.Stack, options Options) DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketTaggingResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketTaggingResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketTaggingResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketTaggingInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketTaggingResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketTaggingResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketVersioning.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketVersioning.go index 6d7943e6f..9e3ddf76b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketVersioning.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketVersioning.go @@ -4,11 +4,17 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -18,32 +24,22 @@ import ( // objects in the bucket. All objects added to the bucket receive a unique version // ID. Suspended—Disables versioning for the objects in the bucket. All objects // added to the bucket receive the version ID null. If the versioning state has -// never been set on a bucket, it has no versioning state; a GetBucketVersioning -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html) +// never been set on a bucket, it has no versioning state; a GetBucketVersioning (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html) // request does not return a versioning state value. In order to enable MFA Delete, // you must be the bucket owner. If you are the bucket owner and want to enable MFA // Delete in the bucket versioning configuration, you must include the x-amz-mfa -// request header and the Status and the MfaDelete request elements in a request to -// set the versioning state of the bucket. If you have an object expiration -// lifecycle policy in your non-versioned bucket and you want to maintain the same -// permanent delete behavior when you enable versioning, you must add a noncurrent -// expiration policy. The noncurrent expiration lifecycle policy will manage the -// deletes of the noncurrent object versions in the version-enabled bucket. (A -// version-enabled bucket maintains one current and zero or more noncurrent object -// versions.) For more information, see Lifecycle and Versioning -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html#lifecycle-and-other-bucket-config). -// Related Resources -// -// * CreateBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) -// -// * -// DeleteBucket -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) -// -// * -// GetBucketVersioning -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html) +// request header and the Status and the MfaDelete request elements in a request +// to set the versioning state of the bucket. If you have an object expiration +// lifecycle configuration in your non-versioned bucket and you want to maintain +// the same permanent delete behavior when you enable versioning, you must add a +// noncurrent expiration policy. The noncurrent expiration lifecycle configuration +// will manage the deletes of the noncurrent object versions in the version-enabled +// bucket. (A version-enabled bucket maintains one current and zero or more +// noncurrent object versions.) For more information, see Lifecycle and Versioning (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html#lifecycle-and-other-bucket-config) +// . The following operations are related to PutBucketVersioning : +// - CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) +// - DeleteBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) +// - GetBucketVersioning (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html) func (c *Client) PutBucketVersioning(ctx context.Context, params *PutBucketVersioningInput, optFns ...func(*Options)) (*PutBucketVersioningOutput, error) { if params == nil { params = &PutBucketVersioningInput{} @@ -75,19 +71,17 @@ type PutBucketVersioningInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm // >The base64-encoded 128-bit MD5 digest of the data. You must use this header as // a message integrity check to verify that the request body was not corrupted in - // transit. For more information, see RFC 1864 - // (http://www.ietf.org/rfc/rfc1864.txt). For requests made using the Amazon Web - // Services Command Line Interface (CLI) or Amazon Web Services SDKs, this field is - // calculated automatically. + // transit. For more information, see RFC 1864 (http://www.ietf.org/rfc/rfc1864.txt) + // . For requests made using the Amazon Web Services Command Line Interface (CLI) + // or Amazon Web Services SDKs, this field is calculated automatically. ContentMD5 *string // The account ID of the expected bucket owner. If the bucket is owned by a @@ -95,8 +89,8 @@ type PutBucketVersioningInput struct { // (access denied). ExpectedBucketOwner *string - // The concatenation of the authentication device's serial number, a space, and the - // value that is displayed on your authentication device. + // The concatenation of the authentication device's serial number, a space, and + // the value that is displayed on your authentication device. MFA *string noSmithyDocumentSerde @@ -118,6 +112,9 @@ func (c *Client) addOperationPutBucketVersioningMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -145,7 +142,7 @@ func (c *Client) addOperationPutBucketVersioningMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -157,6 +154,9 @@ func (c *Client) addOperationPutBucketVersioningMiddlewares(stack *middleware.St if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketVersioningResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketVersioningValidationMiddleware(stack); err != nil { return err } @@ -166,6 +166,9 @@ func (c *Client) addOperationPutBucketVersioningMiddlewares(stack *middleware.St if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketVersioningInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -184,9 +187,22 @@ func (c *Client) addOperationPutBucketVersioningMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketVersioningInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketVersioning(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -196,8 +212,8 @@ func newServiceMetadataMiddleware_opPutBucketVersioning(region string) *awsmiddl } } -// getPutBucketVersioningRequestAlgorithmMember gets the request checksum algorithm -// value provided as input. +// getPutBucketVersioningRequestAlgorithmMember gets the request checksum +// algorithm value provided as input. func getPutBucketVersioningRequestAlgorithmMember(input interface{}) (string, bool) { in := input.(*PutBucketVersioningInput) if len(in.ChecksumAlgorithm) == 0 { @@ -241,3 +257,139 @@ func addPutBucketVersioningUpdateEndpoint(stack *middleware.Stack, options Optio DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketVersioningResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketVersioningResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketVersioningResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketVersioningInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketVersioningResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketVersioningResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketWebsite.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketWebsite.go index 11cb4a355..e21b4c171 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketWebsite.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutBucketWebsite.go @@ -4,11 +4,17 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -17,73 +23,45 @@ import ( // subresource. To configure a bucket as a website, you can add this subresource on // the bucket with website configuration information such as the file name of the // index document and any redirect rules. For more information, see Hosting -// Websites on Amazon S3 -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html). This PUT -// action requires the S3:PutBucketWebsite permission. By default, only the bucket -// owner can configure the website attached to a bucket; however, bucket owners can -// allow other users to set the website configuration by writing a bucket policy -// that grants them the S3:PutBucketWebsite permission. To redirect all website -// requests sent to the bucket's website endpoint, you add a website configuration -// with the following elements. Because all requests are sent to another website, -// you don't need to provide index document name for the bucket. +// Websites on Amazon S3 (https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html) +// . This PUT action requires the S3:PutBucketWebsite permission. By default, only +// the bucket owner can configure the website attached to a bucket; however, bucket +// owners can allow other users to set the website configuration by writing a +// bucket policy that grants them the S3:PutBucketWebsite permission. To redirect +// all website requests sent to the bucket's website endpoint, you add a website +// configuration with the following elements. Because all requests are sent to +// another website, you don't need to provide index document name for the bucket. +// - WebsiteConfiguration +// - RedirectAllRequestsTo +// - HostName +// - Protocol // -// * -// WebsiteConfiguration +// If you want granular control over redirects, you can use the following elements +// to add routing rules that describe conditions for redirecting requests and +// information about the redirect destination. In this case, the website +// configuration must provide an index document for the bucket, because some +// requests might not be redirected. +// - WebsiteConfiguration +// - IndexDocument +// - Suffix +// - ErrorDocument +// - Key +// - RoutingRules +// - RoutingRule +// - Condition +// - HttpErrorCodeReturnedEquals +// - KeyPrefixEquals +// - Redirect +// - Protocol +// - HostName +// - ReplaceKeyPrefixWith +// - ReplaceKeyWith +// - HttpRedirectCode // -// * RedirectAllRequestsTo -// -// * HostName -// -// * Protocol -// -// If you -// want granular control over redirects, you can use the following elements to add -// routing rules that describe conditions for redirecting requests and information -// about the redirect destination. In this case, the website configuration must -// provide an index document for the bucket, because some requests might not be -// redirected. -// -// * WebsiteConfiguration -// -// * IndexDocument -// -// * Suffix -// -// * -// ErrorDocument -// -// * Key -// -// * RoutingRules -// -// * RoutingRule -// -// * Condition -// -// * -// HttpErrorCodeReturnedEquals -// -// * KeyPrefixEquals -// -// * Redirect -// -// * Protocol -// -// * -// HostName -// -// * ReplaceKeyPrefixWith -// -// * ReplaceKeyWith -// -// * HttpRedirectCode -// -// Amazon -// S3 has a limitation of 50 routing rules per website configuration. If you -// require more than 50 routing rules, you can use object redirect. For more -// information, see Configuring an Object Redirect -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html) in -// the Amazon S3 User Guide. +// Amazon S3 has a limitation of 50 routing rules per website configuration. If +// you require more than 50 routing rules, you can use object redirect. For more +// information, see Configuring an Object Redirect (https://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html) +// in the Amazon S3 User Guide. The maximum request length is limited to 128 KB. func (c *Client) PutBucketWebsite(ctx context.Context, params *PutBucketWebsiteInput, optFns ...func(*Options)) (*PutBucketWebsiteOutput, error) { if params == nil { params = &PutBucketWebsiteInput{} @@ -115,19 +93,17 @@ type PutBucketWebsiteInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm - // The base64-encoded 128-bit MD5 digest of the data. You must use this header as a - // message integrity check to verify that the request body was not corrupted in - // transit. For more information, see RFC 1864 - // (http://www.ietf.org/rfc/rfc1864.txt). For requests made using the Amazon Web - // Services Command Line Interface (CLI) or Amazon Web Services SDKs, this field is - // calculated automatically. + // The base64-encoded 128-bit MD5 digest of the data. You must use this header as + // a message integrity check to verify that the request body was not corrupted in + // transit. For more information, see RFC 1864 (http://www.ietf.org/rfc/rfc1864.txt) + // . For requests made using the Amazon Web Services Command Line Interface (CLI) + // or Amazon Web Services SDKs, this field is calculated automatically. ContentMD5 *string // The account ID of the expected bucket owner. If the bucket is owned by a @@ -154,6 +130,9 @@ func (c *Client) addOperationPutBucketWebsiteMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -181,7 +160,7 @@ func (c *Client) addOperationPutBucketWebsiteMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -193,6 +172,9 @@ func (c *Client) addOperationPutBucketWebsiteMiddlewares(stack *middleware.Stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutBucketWebsiteResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutBucketWebsiteValidationMiddleware(stack); err != nil { return err } @@ -202,6 +184,9 @@ func (c *Client) addOperationPutBucketWebsiteMiddlewares(stack *middleware.Stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutBucketWebsiteInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -220,9 +205,22 @@ func (c *Client) addOperationPutBucketWebsiteMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutBucketWebsiteInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutBucketWebsite(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -277,3 +275,139 @@ func addPutBucketWebsiteUpdateEndpoint(stack *middleware.Stack, options Options) DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutBucketWebsiteResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutBucketWebsiteResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutBucketWebsiteResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutBucketWebsiteInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutBucketWebsiteResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutBucketWebsiteResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObject.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObject.go index 643364061..51c2f1fd4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObject.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObject.go @@ -4,12 +4,18 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "io" @@ -18,87 +24,71 @@ import ( // Adds an object to a bucket. You must have WRITE permissions on a bucket to add // an object to it. Amazon S3 never adds partial objects; if you receive a success -// response, Amazon S3 added the entire object to the bucket. Amazon S3 is a -// distributed system. If it receives multiple write requests for the same object -// simultaneously, it overwrites all but the last object written. Amazon S3 does -// not provide object locking; if you need this, make sure to build it into your -// application layer or use versioning instead. To ensure that data is not -// corrupted traversing the network, use the Content-MD5 header. When you use this -// header, Amazon S3 checks the object against the provided MD5 value and, if they -// do not match, returns an error. Additionally, you can calculate the MD5 while -// putting an object to Amazon S3 and compare the returned ETag to the calculated -// MD5 value. +// response, Amazon S3 added the entire object to the bucket. You cannot use +// PutObject to only update a single piece of metadata for an existing object. You +// must put the entire object with updated metadata if you want to update some +// values. Amazon S3 is a distributed system. If it receives multiple write +// requests for the same object simultaneously, it overwrites all but the last +// object written. To prevent objects from being deleted or overwritten, you can +// use Amazon S3 Object Lock (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html) +// . To ensure that data is not corrupted traversing the network, use the +// Content-MD5 header. When you use this header, Amazon S3 checks the object +// against the provided MD5 value and, if they do not match, returns an error. +// Additionally, you can calculate the MD5 while putting an object to Amazon S3 and +// compare the returned ETag to the calculated MD5 value. +// - To successfully complete the PutObject request, you must have the +// s3:PutObject in your IAM permissions. +// - To successfully change the objects acl of your PutObject request, you must +// have the s3:PutObjectAcl in your IAM permissions. +// - To successfully set the tag-set with your PutObject request, you must have +// the s3:PutObjectTagging in your IAM permissions. +// - The Content-MD5 header is required for any request to upload an object with +// a retention period configured using Amazon S3 Object Lock. For more information +// about Amazon S3 Object Lock, see Amazon S3 Object Lock Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html) +// in the Amazon S3 User Guide. // -// * To successfully complete the PutObject request, you must have the -// s3:PutObject in your IAM permissions. -// -// * To successfully change the objects acl -// of your PutObject request, you must have the s3:PutObjectAcl in your IAM -// permissions. -// -// * The Content-MD5 header is required for any request to upload an -// object with a retention period configured using Amazon S3 Object Lock. For more -// information about Amazon S3 Object Lock, see Amazon S3 Object Lock Overview -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html) in -// the Amazon S3 User Guide. -// -// Server-side Encryption You can optionally request -// server-side encryption. With server-side encryption, Amazon S3 encrypts your -// data as it writes it to disks in its data centers and decrypts the data when you -// access it. You have the option to provide your own encryption key or use Amazon -// Web Services managed encryption keys (SSE-S3 or SSE-KMS). For more information, -// see Using Server-Side Encryption -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html). -// If you request server-side encryption using Amazon Web Services Key Management -// Service (SSE-KMS), you can enable an S3 Bucket Key at the object-level. For more -// information, see Amazon S3 Bucket Keys -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html) in the Amazon -// S3 User Guide. Access Control List (ACL)-Specific Request Headers You can use -// headers to grant ACL- based permissions. By default, all objects are private. -// Only the owner has full access control. When adding a new object, you can grant -// permissions to individual Amazon Web Services accounts or to predefined groups -// defined by Amazon S3. These permissions are then added to the ACL on the object. -// For more information, see Access Control List (ACL) Overview -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html) and Managing -// ACLs Using the REST API -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-using-rest-api.html). If -// the bucket that you're uploading objects to uses the bucket owner enforced +// You have four mutually exclusive options to protect data using server-side +// encryption in Amazon S3, depending on how you choose to manage the encryption +// keys. Specifically, the encryption key options are Amazon S3 managed keys +// (SSE-S3), Amazon Web Services KMS keys (SSE-KMS or DSSE-KMS), and +// customer-provided keys (SSE-C). Amazon S3 encrypts data with server-side +// encryption by using Amazon S3 managed keys (SSE-S3) by default. You can +// optionally tell Amazon S3 to encrypt data at rest by using server-side +// encryption with other key options. For more information, see Using Server-Side +// Encryption (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html) +// . When adding a new object, you can use headers to grant ACL-based permissions +// to individual Amazon Web Services accounts or to predefined groups defined by +// Amazon S3. These permissions are then added to the ACL on the object. By +// default, all objects are private. Only the owner has full access control. For +// more information, see Access Control List (ACL) Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html) +// and Managing ACLs Using the REST API (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-using-rest-api.html) +// . If the bucket that you're uploading objects to uses the bucket owner enforced // setting for S3 Object Ownership, ACLs are disabled and no longer affect // permissions. Buckets that use this setting only accept PUT requests that don't // specify an ACL or PUT requests that specify bucket owner full control ACLs, such // as the bucket-owner-full-control canned ACL or an equivalent form of this ACL // expressed in the XML format. PUT requests that contain other ACLs (for example, // custom grants to certain Amazon Web Services accounts) fail and return a 400 -// error with the error code AccessControlListNotSupported. For more information, -// see Controlling ownership of objects and disabling ACLs -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) +// error with the error code AccessControlListNotSupported . For more information, +// see Controlling ownership of objects and disabling ACLs (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) // in the Amazon S3 User Guide. If your bucket uses the bucket owner enforced // setting for Object Ownership, all objects written to the bucket by any account -// will be owned by the bucket owner. Storage Class Options By default, Amazon S3 -// uses the STANDARD Storage Class to store newly created objects. The STANDARD -// storage class provides high durability and high availability. Depending on -// performance needs, you can specify a different Storage Class. Amazon S3 on -// Outposts only uses the OUTPOSTS Storage Class. For more information, see Storage -// Classes -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html) in -// the Amazon S3 User Guide. Versioning If you enable versioning for a bucket, -// Amazon S3 automatically generates a unique version ID for the object being -// stored. Amazon S3 returns this ID in the response. When you enable versioning -// for a bucket, if Amazon S3 receives multiple write requests for the same object -// simultaneously, it stores all of the objects. For more information about -// versioning, see Adding Objects to Versioning Enabled Buckets -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/AddingObjectstoVersioningEnabledBuckets.html). -// For information about returning the versioning state of a bucket, see -// GetBucketVersioning -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html). -// Related Resources -// -// * CopyObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) -// -// * -// DeleteObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) +// will be owned by the bucket owner. By default, Amazon S3 uses the STANDARD +// Storage Class to store newly created objects. The STANDARD storage class +// provides high durability and high availability. Depending on performance needs, +// you can specify a different Storage Class. Amazon S3 on Outposts only uses the +// OUTPOSTS Storage Class. For more information, see Storage Classes (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html) +// in the Amazon S3 User Guide. If you enable versioning for a bucket, Amazon S3 +// automatically generates a unique version ID for the object being stored. Amazon +// S3 returns this ID in the response. When you enable versioning for a bucket, if +// Amazon S3 receives multiple write requests for the same object simultaneously, +// it stores all of the objects. For more information about versioning, see Adding +// Objects to Versioning-Enabled Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/AddingObjectstoVersioningEnabledBuckets.html) +// . For information about returning the versioning state of a bucket, see +// GetBucketVersioning (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html) +// . For more information about related Amazon S3 APIs, see the following: +// - CopyObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) +// - DeleteObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) func (c *Client) PutObject(ctx context.Context, params *PutObjectInput, optFns ...func(*Options)) (*PutObjectOutput, error) { if params == nil { params = &PutObjectInput{} @@ -122,17 +112,15 @@ type PutObjectInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -142,33 +130,31 @@ type PutObjectInput struct { // This member is required. Key *string - // The canned ACL to apply to the object. For more information, see Canned ACL - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL). - // This action is not supported by Amazon S3 on Outposts. + // The canned ACL to apply to the object. For more information, see Canned ACL (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL) + // . This action is not supported by Amazon S3 on Outposts. ACL types.ObjectCannedACL // Object data. Body io.Reader // Specifies whether Amazon S3 should use an S3 Bucket Key for object encryption - // with server-side encryption using AWS KMS (SSE-KMS). Setting this header to true - // causes Amazon S3 to use an S3 Bucket Key for object encryption with SSE-KMS. - // Specifying this header with a PUT action doesn’t affect bucket-level settings - // for S3 Bucket Key. + // with server-side encryption using Key Management Service (KMS) keys (SSE-KMS). + // Setting this header to true causes Amazon S3 to use an S3 Bucket Key for object + // encryption with SSE-KMS. Specifying this header with a PUT action doesn’t affect + // bucket-level settings for S3 Bucket Key. BucketKeyEnabled bool // Can be used to specify caching behavior along the request/reply chain. For more - // information, see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 - // (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9). + // information, see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) + // . CacheControl *string // Indicates the algorithm used to create the checksum for the object when using // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm @@ -176,45 +162,41 @@ type PutObjectInput struct { // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 32-bit CRC32 checksum of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumCRC32 *string // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 32-bit CRC32C checksum of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumCRC32C *string // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 160-bit SHA-1 digest of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumSHA1 *string // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 256-bit SHA-256 digest of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumSHA256 *string // Specifies presentational information for the object. For more information, see - // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1 - // (http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1). + // https://www.rfc-editor.org/rfc/rfc6266#section-4 (https://www.rfc-editor.org/rfc/rfc6266#section-4) + // . ContentDisposition *string // Specifies what content encodings have been applied to the object and thus what // decoding mechanisms must be applied to obtain the media-type referenced by the // Content-Type header field. For more information, see - // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11 - // (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11). + // https://www.rfc-editor.org/rfc/rfc9110.html#field.content-encoding (https://www.rfc-editor.org/rfc/rfc9110.html#field.content-encoding) + // . ContentEncoding *string // The language the content is in. @@ -222,8 +204,8 @@ type PutObjectInput struct { // Size of the body in bytes. This parameter is useful when the size of the body // cannot be determined automatically. For more information, see - // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13 - // (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13). + // https://www.rfc-editor.org/rfc/rfc9110.html#name-content-length (https://www.rfc-editor.org/rfc/rfc9110.html#name-content-length) + // . ContentLength int64 // The base64-encoded 128-bit MD5 digest of the message (without the headers) @@ -231,13 +213,13 @@ type PutObjectInput struct { // verify that the data is the same data that was originally sent. Although it is // optional, we recommend using the Content-MD5 mechanism as an end-to-end // integrity check. For more information about REST request authentication, see - // REST Authentication - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html). + // REST Authentication (https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html) + // . ContentMD5 *string // A standard MIME type describing the format of the contents. For more - // information, see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17 - // (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17). + // information, see https://www.rfc-editor.org/rfc/rfc9110.html#name-content-type (https://www.rfc-editor.org/rfc/rfc9110.html#name-content-type) + // . ContentType *string // The account ID of the expected bucket owner. If the bucket is owned by a @@ -246,8 +228,8 @@ type PutObjectInput struct { ExpectedBucketOwner *string // The date and time at which the object is no longer cacheable. For more - // information, see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21 - // (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21). + // information, see https://www.rfc-editor.org/rfc/rfc7234#section-5.3 (https://www.rfc-editor.org/rfc/rfc7234#section-5.3) + // . Expires *time.Time // Gives the grantee READ, READ_ACP, and WRITE_ACP permissions on the object. This @@ -258,8 +240,8 @@ type PutObjectInput struct { // supported by Amazon S3 on Outposts. GrantRead *string - // Allows grantee to read the object ACL. This action is not supported by Amazon S3 - // on Outposts. + // Allows grantee to read the object ACL. This action is not supported by Amazon + // S3 on Outposts. GrantReadACP *string // Allows grantee to write the ACL for the applicable object. This action is not @@ -270,8 +252,8 @@ type PutObjectInput struct { Metadata map[string]string // Specifies whether a legal hold will be applied to this object. For more - // information about S3 Object Lock, see Object Lock - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html). + // information about S3 Object Lock, see Object Lock (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html) + // . ObjectLockLegalHoldStatus types.ObjectLockLegalHoldStatus // The Object Lock mode that you want to apply to this object. @@ -282,10 +264,11 @@ type PutObjectInput struct { ObjectLockRetainUntilDate *time.Time // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -307,49 +290,50 @@ type PutObjectInput struct { // Specifies the Amazon Web Services KMS Encryption Context to use for object // encryption. The value of this header is a base64-encoded UTF-8 string holding - // JSON with the encryption context key-value pairs. + // JSON with the encryption context key-value pairs. This value is stored as object + // metadata and automatically gets passed on to Amazon Web Services KMS for future + // GetObject or CopyObject operations on this object. SSEKMSEncryptionContext *string - // If x-amz-server-side-encryption is present and has the value of aws:kms, this - // header specifies the ID of the Amazon Web Services Key Management Service - // (Amazon Web Services KMS) symmetrical customer managed key that was used for the - // object. If you specify x-amz-server-side-encryption:aws:kms, but do not provide - // x-amz-server-side-encryption-aws-kms-key-id, Amazon S3 uses the Amazon Web - // Services managed key to protect the data. If the KMS key does not exist in the - // same account issuing the command, you must use the full ARN and not just the ID. + // If x-amz-server-side-encryption has a valid value of aws:kms or aws:kms:dsse , + // this header specifies the ID (Key ID, Key ARN, or Key Alias) of the Key + // Management Service (KMS) symmetric encryption customer managed key that was used + // for the object. If you specify x-amz-server-side-encryption:aws:kms or + // x-amz-server-side-encryption:aws:kms:dsse , but do not provide + // x-amz-server-side-encryption-aws-kms-key-id , Amazon S3 uses the Amazon Web + // Services managed key ( aws/s3 ) to protect the data. If the KMS key does not + // exist in the same account that's issuing the command, you must use the full ARN + // and not just the ID. SSEKMSKeyId *string // The server-side encryption algorithm used when storing this object in Amazon S3 - // (for example, AES256, aws:kms). + // (for example, AES256 , aws:kms , aws:kms:dsse ). ServerSideEncryption types.ServerSideEncryption // By default, Amazon S3 uses the STANDARD Storage Class to store newly created // objects. The STANDARD storage class provides high durability and high // availability. Depending on performance needs, you can specify a different // Storage Class. Amazon S3 on Outposts only uses the OUTPOSTS Storage Class. For - // more information, see Storage Classes - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html) in - // the Amazon S3 User Guide. + // more information, see Storage Classes (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html) + // in the Amazon S3 User Guide. StorageClass types.StorageClass - // The tag-set for the object. The tag-set must be encoded as URL Query parameters. - // (For example, "Key1=Value1") + // The tag-set for the object. The tag-set must be encoded as URL Query + // parameters. (For example, "Key1=Value1") Tagging *string // If the bucket is configured as a website, redirects requests for this object to // another object in the same bucket or to an external URL. Amazon S3 stores the // value of this header in the object metadata. For information about object - // metadata, see Object Key and Metadata - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html). In the - // following example, the request header sets the redirect to an object + // metadata, see Object Key and Metadata (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html) + // . In the following example, the request header sets the redirect to an object // (anotherPage.html) in the same bucket: x-amz-website-redirect-location: // /anotherPage.html In the following example, the request header sets the object // redirect to another website: x-amz-website-redirect-location: // http://www.example.com/ For more information about website hosting in Amazon S3, - // see Hosting Websites on Amazon S3 - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html) and How to - // Configure Website Page Redirects - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html). + // see Hosting Websites on Amazon S3 (https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html) + // and How to Configure Website Page Redirects (https://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html) + // . WebsiteRedirectLocation *string noSmithyDocumentSerde @@ -358,38 +342,34 @@ type PutObjectInput struct { type PutObjectOutput struct { // Indicates whether the uploaded object uses an S3 Bucket Key for server-side - // encryption with Amazon Web Services KMS (SSE-KMS). + // encryption with Key Management Service (KMS) keys (SSE-KMS). BucketKeyEnabled bool // The base64-encoded, 32-bit CRC32 checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32 *string // The base64-encoded, 32-bit CRC32C checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32C *string // The base64-encoded, 160-bit SHA-1 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA1 *string // The base64-encoded, 256-bit SHA-256 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA256 *string @@ -397,9 +377,8 @@ type PutObjectOutput struct { ETag *string // If the expiration is configured for the object (see - // PutBucketLifecycleConfiguration - // (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html)), - // the response includes this header. It includes the expiry-date and rule-id + // PutBucketLifecycleConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html) + // ), the response includes this header. It includes the expiry-date and rule-id // key-value pairs that provide information about object expiration. The value of // the rule-id is URL-encoded. Expiration *string @@ -408,30 +387,30 @@ type PutObjectOutput struct { // request. RequestCharged types.RequestCharged - // If server-side encryption with a customer-provided encryption key was requested, - // the response will include this header confirming the encryption algorithm used. + // If server-side encryption with a customer-provided encryption key was + // requested, the response will include this header confirming the encryption + // algorithm used. SSECustomerAlgorithm *string - // If server-side encryption with a customer-provided encryption key was requested, - // the response will include this header to provide round-trip message integrity - // verification of the customer-provided encryption key. + // If server-side encryption with a customer-provided encryption key was + // requested, the response will include this header to provide round-trip message + // integrity verification of the customer-provided encryption key. SSECustomerKeyMD5 *string // If present, specifies the Amazon Web Services KMS Encryption Context to use for // object encryption. The value of this header is a base64-encoded UTF-8 string - // holding JSON with the encryption context key-value pairs. + // holding JSON with the encryption context key-value pairs. This value is stored + // as object metadata and automatically gets passed on to Amazon Web Services KMS + // for future GetObject or CopyObject operations on this object. SSEKMSEncryptionContext *string - // If x-amz-server-side-encryption is present and has the value of aws:kms, this - // header specifies the ID of the Amazon Web Services Key Management Service - // (Amazon Web Services KMS) symmetric customer managed key that was used for the - // object. + // If x-amz-server-side-encryption has a valid value of aws:kms or aws:kms:dsse , + // this header specifies the ID of the Key Management Service (KMS) symmetric + // encryption customer managed key that was used for the object. SSEKMSKeyId *string - // If you specified server-side encryption either with an Amazon Web Services KMS - // key or Amazon S3-managed encryption key in your PUT request, the response - // includes this header. It confirms the encryption algorithm that Amazon S3 used - // to encrypt the object. + // The server-side encryption algorithm used when storing this object in Amazon S3 + // (for example, AES256 , aws:kms , aws:kms:dsse ). ServerSideEncryption types.ServerSideEncryption // Version of the object. @@ -452,6 +431,9 @@ func (c *Client) addOperationPutObjectMiddlewares(stack *middleware.Stack, optio if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -479,7 +461,7 @@ func (c *Client) addOperationPutObjectMiddlewares(stack *middleware.Stack, optio if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -491,6 +473,9 @@ func (c *Client) addOperationPutObjectMiddlewares(stack *middleware.Stack, optio if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutObjectResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutObjectValidationMiddleware(stack); err != nil { return err } @@ -500,6 +485,12 @@ func (c *Client) addOperationPutObjectMiddlewares(stack *middleware.Stack, optio if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = add100Continue(stack, options); err != nil { + return err + } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutObjectInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -521,9 +512,22 @@ func (c *Client) addOperationPutObjectMiddlewares(stack *middleware.Stack, optio if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutObjectInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutObject(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -611,3 +615,139 @@ func addPutObjectPayloadAsUnsigned(stack *middleware.Stack, options Options) err v4.RemoveComputePayloadSHA256Middleware(stack) return v4.AddUnsignedPayloadMiddleware(stack) } + +type opPutObjectResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutObjectResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutObjectResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutObjectInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutObjectResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutObjectResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectAcl.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectAcl.go index 05a377b5b..22a0dcc22 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectAcl.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectAcl.go @@ -4,11 +4,17 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -16,137 +22,84 @@ import ( // Uses the acl subresource to set the access control list (ACL) permissions for a // new or existing object in an S3 bucket. You must have WRITE_ACP permission to // set the ACL of an object. For more information, see What permissions can I -// grant? -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#permissions) +// grant? (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#permissions) // in the Amazon S3 User Guide. This action is not supported by Amazon S3 on // Outposts. Depending on your application needs, you can choose to set the ACL on // an object using either the request body or the headers. For example, if you have // an existing application that updates a bucket ACL using the request body, you -// can continue to use that approach. For more information, see Access Control List -// (ACL) Overview -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html) in the -// Amazon S3 User Guide. If your bucket uses the bucket owner enforced setting for -// S3 Object Ownership, ACLs are disabled and no longer affect permissions. You -// must use policies to grant access to your bucket and the objects in it. Requests -// to set ACLs or update ACLs fail and return the AccessControlListNotSupported -// error code. Requests to read ACLs are still supported. For more information, see -// Controlling object ownership -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) -// in the Amazon S3 User Guide. Access Permissions You can set access permissions -// using one of the following methods: +// can continue to use that approach. For more information, see Access Control +// List (ACL) Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html) +// in the Amazon S3 User Guide. If your bucket uses the bucket owner enforced +// setting for S3 Object Ownership, ACLs are disabled and no longer affect +// permissions. You must use policies to grant access to your bucket and the +// objects in it. Requests to set ACLs or update ACLs fail and return the +// AccessControlListNotSupported error code. Requests to read ACLs are still +// supported. For more information, see Controlling object ownership (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) +// in the Amazon S3 User Guide. Permissions You can set access permissions using +// one of the following methods: +// - Specify a canned ACL with the x-amz-acl request header. Amazon S3 supports a +// set of predefined ACLs, known as canned ACLs. Each canned ACL has a predefined +// set of grantees and permissions. Specify the canned ACL name as the value of +// x-amz-ac l. If you use this header, you cannot use other access +// control-specific headers in your request. For more information, see Canned ACL (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL) +// . +// - Specify access permissions explicitly with the x-amz-grant-read , +// x-amz-grant-read-acp , x-amz-grant-write-acp , and x-amz-grant-full-control +// headers. When using these headers, you specify explicit access permissions and +// grantees (Amazon Web Services accounts or Amazon S3 groups) who will receive the +// permission. If you use these ACL-specific headers, you cannot use x-amz-acl +// header to set a canned ACL. These parameters map to the set of permissions that +// Amazon S3 supports in an ACL. For more information, see Access Control List +// (ACL) Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html) +// . You specify each grantee as a type=value pair, where the type is one of the +// following: +// - id – if the value specified is the canonical user ID of an Amazon Web +// Services account +// - uri – if you are granting permissions to a predefined group +// - emailAddress – if the value specified is the email address of an Amazon Web +// Services account Using email addresses to specify a grantee is only supported in +// the following Amazon Web Services Regions: +// - US East (N. Virginia) +// - US West (N. California) +// - US West (Oregon) +// - Asia Pacific (Singapore) +// - Asia Pacific (Sydney) +// - Asia Pacific (Tokyo) +// - Europe (Ireland) +// - South America (São Paulo) For a list of all the Amazon S3 supported Regions +// and endpoints, see Regions and Endpoints (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) +// in the Amazon Web Services General Reference. For example, the following +// x-amz-grant-read header grants list objects permission to the two Amazon Web +// Services accounts identified by their email addresses. x-amz-grant-read: +// emailAddress="xyz@amazon.com", emailAddress="abc@amazon.com" // -// * Specify a canned ACL with the x-amz-acl -// request header. Amazon S3 supports a set of predefined ACLs, known as canned -// ACLs. Each canned ACL has a predefined set of grantees and permissions. Specify -// the canned ACL name as the value of x-amz-acl. If you use this header, you -// cannot use other access control-specific headers in your request. For more -// information, see Canned ACL -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL). +// You can use either a canned ACL or specify access permissions explicitly. You +// cannot do both. Grantee Values You can specify the person (grantee) to whom +// you're assigning access rights (using request elements) in the following ways: +// - By the person's ID: <>ID<><>GranteesEmail<> DisplayName is optional and +// ignored in the request. +// - By URI: <>http://acs.amazonaws.com/groups/global/AuthenticatedUsers<> +// - By Email address: <>Grantees@email.com<>lt;/Grantee> The grantee is resolved +// to the CanonicalUser and, in a response to a GET Object acl request, appears as +// the CanonicalUser. Using email addresses to specify a grantee is only supported +// in the following Amazon Web Services Regions: +// - US East (N. Virginia) +// - US West (N. California) +// - US West (Oregon) +// - Asia Pacific (Singapore) +// - Asia Pacific (Sydney) +// - Asia Pacific (Tokyo) +// - Europe (Ireland) +// - South America (São Paulo) For a list of all the Amazon S3 supported Regions +// and endpoints, see Regions and Endpoints (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) +// in the Amazon Web Services General Reference. // -// * -// Specify access permissions explicitly with the x-amz-grant-read, -// x-amz-grant-read-acp, x-amz-grant-write-acp, and x-amz-grant-full-control -// headers. When using these headers, you specify explicit access permissions and -// grantees (Amazon Web Services accounts or Amazon S3 groups) who will receive the -// permission. If you use these ACL-specific headers, you cannot use x-amz-acl -// header to set a canned ACL. These parameters map to the set of permissions that -// Amazon S3 supports in an ACL. For more information, see Access Control List -// (ACL) Overview -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html). You specify -// each grantee as a type=value pair, where the type is one of the following: -// -// * id -// – if the value specified is the canonical user ID of an Amazon Web Services -// account -// -// * uri – if you are granting permissions to a predefined group -// -// * -// emailAddress – if the value specified is the email address of an Amazon Web -// Services account Using email addresses to specify a grantee is only supported in -// the following Amazon Web Services Regions: -// -// * US East (N. Virginia) -// -// * US West -// (N. California) -// -// * US West (Oregon) -// -// * Asia Pacific (Singapore) -// -// * Asia Pacific -// (Sydney) -// -// * Asia Pacific (Tokyo) -// -// * Europe (Ireland) -// -// * South America (São -// Paulo) -// -// For a list of all the Amazon S3 supported Regions and endpoints, see -// Regions and Endpoints -// (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the -// Amazon Web Services General Reference. -// -// For example, the following -// x-amz-grant-read header grants list objects permission to the two Amazon Web -// Services accounts identified by their email addresses. x-amz-grant-read: -// emailAddress="xyz@amazon.com", emailAddress="abc@amazon.com" -// -// You can use either -// a canned ACL or specify access permissions explicitly. You cannot do both. -// Grantee Values You can specify the person (grantee) to whom you're assigning -// access rights (using request elements) in the following ways: -// -// * By the person's -// ID: <>ID<><>GranteesEmail<> DisplayName is optional and ignored in the -// request. -// -// * By URI: -// <>http://acs.amazonaws.com/groups/global/AuthenticatedUsers<> -// -// * By Email -// address: <>Grantees@email.com<>lt;/Grantee> The grantee is resolved to the -// CanonicalUser and, in a response to a GET Object acl request, appears as the -// CanonicalUser. Using email addresses to specify a grantee is only supported in -// the following Amazon Web Services Regions: -// -// * US East (N. Virginia) -// -// * US West -// (N. California) -// -// * US West (Oregon) -// -// * Asia Pacific (Singapore) -// -// * Asia Pacific -// (Sydney) -// -// * Asia Pacific (Tokyo) -// -// * Europe (Ireland) -// -// * South America (São -// Paulo) -// -// For a list of all the Amazon S3 supported Regions and endpoints, see -// Regions and Endpoints -// (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the -// Amazon Web Services General Reference. -// -// Versioning The ACL of an object is set -// at the object version level. By default, PUT sets the ACL of the current version -// of an object. To set the ACL of a different version, use the versionId -// subresource. Related Resources -// -// * CopyObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) -// -// * -// GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// Versioning The ACL of an object is set at the object version level. By default, +// PUT sets the ACL of the current version of an object. To set the ACL of a +// different version, use the versionId subresource. The following operations are +// related to PutObjectAcl : +// - CopyObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) +// - GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) func (c *Client) PutObjectAcl(ctx context.Context, params *PutObjectAclInput, optFns ...func(*Options)) (*PutObjectAclOutput, error) { if params == nil { params = &PutObjectAclInput{} @@ -170,8 +123,7 @@ type PutObjectAclInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) // in the Amazon S3 User Guide. // // This member is required. @@ -183,23 +135,21 @@ type PutObjectAclInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Key *string - // The canned ACL to apply to the object. For more information, see Canned ACL - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL). + // The canned ACL to apply to the object. For more information, see Canned ACL (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL) + // . ACL types.ObjectCannedACL // Contains the elements that set the ACL permissions for an object per grantee. @@ -209,19 +159,17 @@ type PutObjectAclInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm - // The base64-encoded 128-bit MD5 digest of the data. This header must be used as a - // message integrity check to verify that the request body was not corrupted in - // transit. For more information, go to RFC 1864.> - // (http://www.ietf.org/rfc/rfc1864.txt) For requests made using the Amazon Web - // Services Command Line Interface (CLI) or Amazon Web Services SDKs, this field is - // calculated automatically. + // The base64-encoded 128-bit MD5 digest of the data. This header must be used as + // a message integrity check to verify that the request body was not corrupted in + // transit. For more information, go to RFC 1864.> (http://www.ietf.org/rfc/rfc1864.txt) + // For requests made using the Amazon Web Services Command Line Interface (CLI) or + // Amazon Web Services SDKs, this field is calculated automatically. ContentMD5 *string // The account ID of the expected bucket owner. If the bucket is owned by a @@ -237,8 +185,8 @@ type PutObjectAclInput struct { // by Amazon S3 on Outposts. GrantRead *string - // Allows grantee to read the bucket ACL. This action is not supported by Amazon S3 - // on Outposts. + // Allows grantee to read the bucket ACL. This action is not supported by Amazon + // S3 on Outposts. GrantReadACP *string // Allows grantee to create new objects in the bucket. For the bucket and object @@ -251,10 +199,11 @@ type PutObjectAclInput struct { GrantWriteACP *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -285,6 +234,9 @@ func (c *Client) addOperationPutObjectAclMiddlewares(stack *middleware.Stack, op if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -312,7 +264,7 @@ func (c *Client) addOperationPutObjectAclMiddlewares(stack *middleware.Stack, op if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -324,6 +276,9 @@ func (c *Client) addOperationPutObjectAclMiddlewares(stack *middleware.Stack, op if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutObjectAclResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutObjectAclValidationMiddleware(stack); err != nil { return err } @@ -333,6 +288,9 @@ func (c *Client) addOperationPutObjectAclMiddlewares(stack *middleware.Stack, op if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutObjectAclInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -351,9 +309,22 @@ func (c *Client) addOperationPutObjectAclMiddlewares(stack *middleware.Stack, op if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutObjectAclInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutObjectAcl(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -408,3 +379,139 @@ func addPutObjectAclUpdateEndpoint(stack *middleware.Stack, options Options) err DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutObjectAclResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutObjectAclResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutObjectAclResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutObjectAclInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutObjectAclResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutObjectAclResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectLegalHold.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectLegalHold.go index b8004b598..d4d371df7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectLegalHold.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectLegalHold.go @@ -4,19 +4,24 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Applies a legal hold configuration to the specified object. For more -// information, see Locking Objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html). This action -// is not supported by Amazon S3 on Outposts. +// information, see Locking Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html) +// . This action is not supported by Amazon S3 on Outposts. func (c *Client) PutObjectLegalHold(ctx context.Context, params *PutObjectLegalHoldInput, optFns ...func(*Options)) (*PutObjectLegalHoldOutput, error) { if params == nil { params = &PutObjectLegalHoldInput{} @@ -40,8 +45,7 @@ type PutObjectLegalHoldInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) // in the Amazon S3 User Guide. // // This member is required. @@ -56,9 +60,8 @@ type PutObjectLegalHoldInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm @@ -78,10 +81,11 @@ type PutObjectLegalHoldInput struct { LegalHold *types.ObjectLockLegalHold // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -112,6 +116,9 @@ func (c *Client) addOperationPutObjectLegalHoldMiddlewares(stack *middleware.Sta if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -139,7 +146,7 @@ func (c *Client) addOperationPutObjectLegalHoldMiddlewares(stack *middleware.Sta if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -151,6 +158,9 @@ func (c *Client) addOperationPutObjectLegalHoldMiddlewares(stack *middleware.Sta if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutObjectLegalHoldResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutObjectLegalHoldValidationMiddleware(stack); err != nil { return err } @@ -160,6 +170,9 @@ func (c *Client) addOperationPutObjectLegalHoldMiddlewares(stack *middleware.Sta if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutObjectLegalHoldInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -178,9 +191,22 @@ func (c *Client) addOperationPutObjectLegalHoldMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutObjectLegalHoldInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutObjectLegalHold(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -235,3 +261,139 @@ func addPutObjectLegalHoldUpdateEndpoint(stack *middleware.Stack, options Option DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutObjectLegalHoldResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutObjectLegalHoldResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutObjectLegalHoldResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutObjectLegalHoldInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutObjectLegalHoldResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutObjectLegalHoldResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectLockConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectLockConfiguration.go index 9740967a7..5b4a897e5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectLockConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectLockConfiguration.go @@ -4,30 +4,30 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) // Places an Object Lock configuration on the specified bucket. The rule specified // in the Object Lock configuration will be applied by default to every new object -// placed in the specified bucket. For more information, see Locking Objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html). -// -// * The -// DefaultRetention settings require both a mode and a period. -// -// * The -// DefaultRetention period can be either Days or Years but you must select one. You -// cannot specify Days and Years at the same time. -// -// * You can only enable Object -// Lock for new buckets. If you want to turn on Object Lock for an existing bucket, -// contact Amazon Web Services Support. +// placed in the specified bucket. For more information, see Locking Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html) +// . +// - The DefaultRetention settings require both a mode and a period. +// - The DefaultRetention period can be either Days or Years but you must select +// one. You cannot specify Days and Years at the same time. +// - You can only enable Object Lock for new buckets. If you want to turn on +// Object Lock for an existing bucket, contact Amazon Web Services Support. func (c *Client) PutObjectLockConfiguration(ctx context.Context, params *PutObjectLockConfigurationInput, optFns ...func(*Options)) (*PutObjectLockConfigurationOutput, error) { if params == nil { params = &PutObjectLockConfigurationInput{} @@ -54,9 +54,8 @@ type PutObjectLockConfigurationInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm @@ -75,10 +74,11 @@ type PutObjectLockConfigurationInput struct { ObjectLockConfiguration *types.ObjectLockConfiguration // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -109,6 +109,9 @@ func (c *Client) addOperationPutObjectLockConfigurationMiddlewares(stack *middle if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -136,7 +139,7 @@ func (c *Client) addOperationPutObjectLockConfigurationMiddlewares(stack *middle if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -148,6 +151,9 @@ func (c *Client) addOperationPutObjectLockConfigurationMiddlewares(stack *middle if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutObjectLockConfigurationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutObjectLockConfigurationValidationMiddleware(stack); err != nil { return err } @@ -157,6 +163,9 @@ func (c *Client) addOperationPutObjectLockConfigurationMiddlewares(stack *middle if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutObjectLockConfigurationInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -175,9 +184,22 @@ func (c *Client) addOperationPutObjectLockConfigurationMiddlewares(stack *middle if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutObjectLockConfigurationInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutObjectLockConfiguration(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -207,9 +229,9 @@ func addPutObjectLockConfigurationInputChecksumMiddlewares(stack *middleware.Sta }) } -// getPutObjectLockConfigurationBucketMember returns a pointer to string denoting a -// provided bucket member valueand a boolean indicating if the input has a modeled -// bucket name, +// getPutObjectLockConfigurationBucketMember returns a pointer to string denoting +// a provided bucket member valueand a boolean indicating if the input has a +// modeled bucket name, func getPutObjectLockConfigurationBucketMember(input interface{}) (*string, bool) { in := input.(*PutObjectLockConfigurationInput) if in.Bucket == nil { @@ -232,3 +254,139 @@ func addPutObjectLockConfigurationUpdateEndpoint(stack *middleware.Stack, option DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutObjectLockConfigurationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutObjectLockConfigurationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutObjectLockConfigurationResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutObjectLockConfigurationInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutObjectLockConfigurationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutObjectLockConfigurationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectRetention.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectRetention.go index c4918f3cb..95176ea69 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectRetention.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectRetention.go @@ -4,22 +4,27 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Places an Object Retention configuration on an object. For more information, see -// Locking Objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html). Users or -// accounts require the s3:PutObjectRetention permission in order to place an -// Object Retention configuration on objects. Bypassing a Governance Retention -// configuration requires the s3:BypassGovernanceRetention permission. This action -// is not supported by Amazon S3 on Outposts. +// Places an Object Retention configuration on an object. For more information, +// see Locking Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html) +// . Users or accounts require the s3:PutObjectRetention permission in order to +// place an Object Retention configuration on objects. Bypassing a Governance +// Retention configuration requires the s3:BypassGovernanceRetention permission. +// This action is not supported by Amazon S3 on Outposts. func (c *Client) PutObjectRetention(ctx context.Context, params *PutObjectRetentionInput, optFns ...func(*Options)) (*PutObjectRetentionOutput, error) { if params == nil { params = &PutObjectRetentionInput{} @@ -37,14 +42,13 @@ func (c *Client) PutObjectRetention(ctx context.Context, params *PutObjectRetent type PutObjectRetentionInput struct { - // The bucket name that contains the object you want to apply this Object Retention - // configuration to. When using this action with an access point, you must direct - // requests to the access point hostname. The access point hostname takes the form - // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this - // action with an access point through the Amazon Web Services SDKs, you provide - // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // The bucket name that contains the object you want to apply this Object + // Retention configuration to. When using this action with an access point, you + // must direct requests to the access point hostname. The access point hostname + // takes the form AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. + // When using this action with an access point through the Amazon Web Services + // SDKs, you provide the access point ARN in place of the bucket name. For more + // information about access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) // in the Amazon S3 User Guide. // // This member is required. @@ -63,9 +67,8 @@ type PutObjectRetentionInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm @@ -81,10 +84,11 @@ type PutObjectRetentionInput struct { ExpectedBucketOwner *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -119,6 +123,9 @@ func (c *Client) addOperationPutObjectRetentionMiddlewares(stack *middleware.Sta if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -146,7 +153,7 @@ func (c *Client) addOperationPutObjectRetentionMiddlewares(stack *middleware.Sta if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -158,6 +165,9 @@ func (c *Client) addOperationPutObjectRetentionMiddlewares(stack *middleware.Sta if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutObjectRetentionResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutObjectRetentionValidationMiddleware(stack); err != nil { return err } @@ -167,6 +177,9 @@ func (c *Client) addOperationPutObjectRetentionMiddlewares(stack *middleware.Sta if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutObjectRetentionInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -185,9 +198,22 @@ func (c *Client) addOperationPutObjectRetentionMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutObjectRetentionInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutObjectRetention(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -242,3 +268,139 @@ func addPutObjectRetentionUpdateEndpoint(stack *middleware.Stack, options Option DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutObjectRetentionResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutObjectRetentionResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutObjectRetentionResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutObjectRetentionInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutObjectRetentionResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutObjectRetentionResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectTagging.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectTagging.go index 43effb9eb..e9785b934 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectTagging.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutObjectTagging.go @@ -4,65 +4,49 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Sets the supplied tag-set to an object that already exists in a bucket. A tag is -// a key-value pair. You can associate tags with an object by sending a PUT request -// against the tagging subresource that is associated with the object. You can -// retrieve tags by sending a GET request. For more information, see -// GetObjectTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html). For -// tagging-related restrictions related to characters and encodings, see Tag -// Restrictions -// (https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/allocation-tag-restrictions.html). -// Note that Amazon S3 limits the maximum number of tags to 10 tags per object. To -// use this operation, you must have permission to perform the s3:PutObjectTagging -// action. By default, the bucket owner has this permission and can grant this -// permission to others. To put tags of any other version, use the versionId query -// parameter. You also need permission for the s3:PutObjectVersionTagging action. -// For information about the Amazon S3 object tagging feature, see Object Tagging -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html). Special -// Errors +// Sets the supplied tag-set to an object that already exists in a bucket. A tag +// is a key-value pair. For more information, see Object Tagging (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-tagging.html) +// . You can associate tags with an object by sending a PUT request against the +// tagging subresource that is associated with the object. You can retrieve tags by +// sending a GET request. For more information, see GetObjectTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html) +// . For tagging-related restrictions related to characters and encodings, see Tag +// Restrictions (https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/allocation-tag-restrictions.html) +// . Note that Amazon S3 limits the maximum number of tags to 10 tags per object. +// To use this operation, you must have permission to perform the +// s3:PutObjectTagging action. By default, the bucket owner has this permission and +// can grant this permission to others. To put tags of any other version, use the +// versionId query parameter. You also need permission for the +// s3:PutObjectVersionTagging action. PutObjectTagging has the following special +// errors. For more Amazon S3 errors see, Error Responses (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html) +// . +// - InvalidTag - The tag provided was not a valid tag. This error can occur if +// the tag did not pass input validation. For more information, see Object +// Tagging (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-tagging.html) +// . +// - MalformedXML - The XML provided does not match the schema. +// - OperationAborted - A conflicting conditional action is currently in progress +// against this resource. Please try again. +// - InternalError - The service was unable to apply the provided tag to the +// object. // -// * Code: InvalidTagError -// -// * Cause: The tag provided was not a valid tag. -// This error can occur if the tag did not pass input validation. For more -// information, see Object Tagging -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html). -// -// * Code: -// MalformedXMLError -// -// * Cause: The XML provided does not match the schema. -// -// * Code: -// OperationAbortedError -// -// * Cause: A conflicting conditional action is currently in -// progress against this resource. Please try again. -// -// * Code: InternalError -// -// * -// Cause: The service was unable to apply the provided tag to the object. -// -// Related -// Resources -// -// * GetObjectTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html) -// -// * -// DeleteObjectTagging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html) +// The following operations are related to PutObjectTagging : +// - GetObjectTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html) +// - DeleteObjectTagging (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html) func (c *Client) PutObjectTagging(ctx context.Context, params *PutObjectTaggingInput, optFns ...func(*Options)) (*PutObjectTaggingOutput, error) { if params == nil { params = &PutObjectTaggingInput{} @@ -86,17 +70,15 @@ type PutObjectTaggingInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -115,9 +97,8 @@ type PutObjectTaggingInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm @@ -133,10 +114,11 @@ type PutObjectTaggingInput struct { ExpectedBucketOwner *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -166,6 +148,9 @@ func (c *Client) addOperationPutObjectTaggingMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -193,7 +178,7 @@ func (c *Client) addOperationPutObjectTaggingMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -205,6 +190,9 @@ func (c *Client) addOperationPutObjectTaggingMiddlewares(stack *middleware.Stack if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutObjectTaggingResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutObjectTaggingValidationMiddleware(stack); err != nil { return err } @@ -214,6 +202,9 @@ func (c *Client) addOperationPutObjectTaggingMiddlewares(stack *middleware.Stack if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutObjectTaggingInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -232,9 +223,22 @@ func (c *Client) addOperationPutObjectTaggingMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutObjectTaggingInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutObjectTagging(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -289,3 +293,139 @@ func addPutObjectTaggingUpdateEndpoint(stack *middleware.Stack, options Options) DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutObjectTaggingResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutObjectTaggingResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutObjectTaggingResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutObjectTaggingInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutObjectTaggingResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutObjectTaggingResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutPublicAccessBlock.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutPublicAccessBlock.go index 922102b58..8aa349c74 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutPublicAccessBlock.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_PutPublicAccessBlock.go @@ -4,44 +4,37 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Creates or modifies the PublicAccessBlock configuration for an Amazon S3 bucket. -// To use this operation, you must have the s3:PutBucketPublicAccessBlock +// Creates or modifies the PublicAccessBlock configuration for an Amazon S3 +// bucket. To use this operation, you must have the s3:PutBucketPublicAccessBlock // permission. For more information about Amazon S3 permissions, see Specifying -// Permissions in a Policy -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html). -// When Amazon S3 evaluates the PublicAccessBlock configuration for a bucket or an -// object, it checks the PublicAccessBlock configuration for both the bucket (or -// the bucket that contains the object) and the bucket owner's account. If the +// Permissions in a Policy (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html) +// . When Amazon S3 evaluates the PublicAccessBlock configuration for a bucket or +// an object, it checks the PublicAccessBlock configuration for both the bucket +// (or the bucket that contains the object) and the bucket owner's account. If the // PublicAccessBlock configurations are different between the bucket and the -// account, Amazon S3 uses the most restrictive combination of the bucket-level and +// account, S3 uses the most restrictive combination of the bucket-level and // account-level settings. For more information about when Amazon S3 considers a -// bucket or an object public, see The Meaning of "Public" -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html#access-control-block-public-access-policy-status). -// Related Resources -// -// * GetPublicAccessBlock -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetPublicAccessBlock.html) -// -// * -// DeletePublicAccessBlock -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeletePublicAccessBlock.html) -// -// * -// GetBucketPolicyStatus -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketPolicyStatus.html) -// -// * -// Using Amazon S3 Block Public Access -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html) +// bucket or an object public, see The Meaning of "Public" (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html#access-control-block-public-access-policy-status) +// . The following operations are related to PutPublicAccessBlock : +// - GetPublicAccessBlock (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetPublicAccessBlock.html) +// - DeletePublicAccessBlock (https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeletePublicAccessBlock.html) +// - GetBucketPolicyStatus (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketPolicyStatus.html) +// - Using Amazon S3 Block Public Access (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html) func (c *Client) PutPublicAccessBlock(ctx context.Context, params *PutPublicAccessBlockInput, optFns ...func(*Options)) (*PutPublicAccessBlockOutput, error) { if params == nil { params = &PutPublicAccessBlockInput{} @@ -68,8 +61,7 @@ type PutPublicAccessBlockInput struct { // The PublicAccessBlock configuration that you want to apply to this Amazon S3 // bucket. You can enable the configuration options in any combination. For more // information about when Amazon S3 considers a bucket or object public, see The - // Meaning of "Public" - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html#access-control-block-public-access-policy-status) + // Meaning of "Public" (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html#access-control-block-public-access-policy-status) // in the Amazon S3 User Guide. // // This member is required. @@ -79,9 +71,8 @@ type PutPublicAccessBlockInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm @@ -115,6 +106,9 @@ func (c *Client) addOperationPutPublicAccessBlockMiddlewares(stack *middleware.S if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -142,7 +136,7 @@ func (c *Client) addOperationPutPublicAccessBlockMiddlewares(stack *middleware.S if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -154,6 +148,9 @@ func (c *Client) addOperationPutPublicAccessBlockMiddlewares(stack *middleware.S if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addPutPublicAccessBlockResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpPutPublicAccessBlockValidationMiddleware(stack); err != nil { return err } @@ -163,6 +160,9 @@ func (c *Client) addOperationPutPublicAccessBlockMiddlewares(stack *middleware.S if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addPutPublicAccessBlockInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -181,9 +181,22 @@ func (c *Client) addOperationPutPublicAccessBlockMiddlewares(stack *middleware.S if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *PutPublicAccessBlockInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opPutPublicAccessBlock(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -238,3 +251,139 @@ func addPutPublicAccessBlockUpdateEndpoint(stack *middleware.Stack, options Opti DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opPutPublicAccessBlockResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opPutPublicAccessBlockResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opPutPublicAccessBlockResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*PutPublicAccessBlockInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addPutPublicAccessBlockResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opPutPublicAccessBlockResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_RestoreObject.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_RestoreObject.go index 45a2aee6a..0ccf96b3f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_RestoreObject.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_RestoreObject.go @@ -4,11 +4,17 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -16,221 +22,151 @@ import ( // Restores an archived copy of an object back into Amazon S3 This action is not // supported by Amazon S3 on Outposts. This action performs the following types of // requests: +// - select - Perform a select query on an archived object +// - restore an archive - Restore an archived object // -// * select - Perform a select query on an archived object -// -// * restore an -// archive - Restore an archived object -// -// To use this operation, you must have -// permissions to perform the s3:RestoreObject action. The bucket owner has this -// permission by default and can grant this permission to others. For more -// information about permissions, see Permissions Related to Bucket Subresource -// Operations -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) -// and Managing Access Permissions to Your Amazon S3 Resources -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) -// in the Amazon S3 User Guide. Querying Archives with Select Requests You use a -// select type of request to perform SQL queries on archived objects. The archived -// objects that are being queried by the select request must be formatted as -// uncompressed comma-separated values (CSV) files. You can run queries and custom -// analytics on your archived data without having to restore your data to a hotter -// Amazon S3 tier. For an overview about select requests, see Querying Archived -// Objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/querying-glacier-archives.html) -// in the Amazon S3 User Guide. When making a select request, do the following: -// -// * -// Define an output location for the select query's output. This must be an Amazon -// S3 bucket in the same Amazon Web Services Region as the bucket that contains the -// archive object that is being queried. The Amazon Web Services account that -// initiates the job must have permissions to write to the S3 bucket. You can -// specify the storage class and encryption for the output objects stored in the -// bucket. For more information about output, see Querying Archived Objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/querying-glacier-archives.html) -// in the Amazon S3 User Guide. For more information about the S3 structure in the -// request body, see the following: -// -// * PutObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) -// -// * Managing -// Access with ACLs -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/S3_ACLs_UsingACLs.html) in the -// Amazon S3 User Guide -// -// * Protecting Data Using Server-Side Encryption -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html) in -// the Amazon S3 User Guide -// -// * Define the SQL expression for the SELECT type of -// restoration for your query in the request body's SelectParameters structure. You -// can use expressions like the following examples. -// -// * The following expression -// returns all records from the specified object. SELECT * FROM Object -// -// * Assuming -// that you are not using any headers for data stored in the object, you can -// specify columns with positional headers. SELECT s._1, s._2 FROM Object s WHERE -// s._3 > 100 -// -// * If you have headers and you set the fileHeaderInfo in the CSV -// structure in the request body to USE, you can specify headers in the query. (If -// you set the fileHeaderInfo field to IGNORE, the first row is skipped for the -// query.) You cannot mix ordinal positions with header column names. SELECT s.Id, -// s.FirstName, s.SSN FROM S3Object s -// -// For more information about using SQL with S3 -// Glacier Select restore, see SQL Reference for Amazon S3 Select and S3 Glacier -// Select -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/s3-glacier-select-sql-reference.html) -// in the Amazon S3 User Guide. When making a select request, you can also do the +// For more information about the S3 structure in the request body, see the // following: -// -// * To expedite your queries, specify the Expedited tier. For more -// information about tiers, see "Restoring Archives," later in this topic. -// -// * -// Specify details about the data serialization format of both the input object -// that is being queried and the serialization of the CSV-encoded query -// results. -// -// The following are additional important facts about the select -// feature: -// -// * The output results are new Amazon S3 objects. Unlike archive -// retrievals, they are stored until explicitly deleted-manually or through a -// lifecycle policy. -// -// * You can issue more than one select request on the same -// Amazon S3 object. Amazon S3 doesn't deduplicate requests, so avoid issuing -// duplicate requests. -// -// * Amazon S3 accepts a select request even if the object has -// already been restored. A select request doesn’t return error response -// 409. -// -// Restoring objects Objects that you archive to the S3 Glacier or S3 Glacier -// Deep Archive storage class, and S3 Intelligent-Tiering Archive or S3 -// Intelligent-Tiering Deep Archive tiers are not accessible in real time. For -// objects in Archive Access or Deep Archive Access tiers you must first initiate a +// - PutObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) +// - Managing Access with ACLs (https://docs.aws.amazon.com/AmazonS3/latest/dev/S3_ACLs_UsingACLs.html) +// in the Amazon S3 User Guide +// - Protecting Data Using Server-Side Encryption (https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html) +// in the Amazon S3 User Guide +// +// Define the SQL expression for the SELECT type of restoration for your query in +// the request body's SelectParameters structure. You can use expressions like the +// following examples. +// - The following expression returns all records from the specified object. +// SELECT * FROM Object +// - Assuming that you are not using any headers for data stored in the object, +// you can specify columns with positional headers. SELECT s._1, s._2 FROM +// Object s WHERE s._3 > 100 +// - If you have headers and you set the fileHeaderInfo in the CSV structure in +// the request body to USE , you can specify headers in the query. (If you set +// the fileHeaderInfo field to IGNORE , the first row is skipped for the query.) +// You cannot mix ordinal positions with header column names. SELECT s.Id, +// s.FirstName, s.SSN FROM S3Object s +// +// When making a select request, you can also do the following: +// - To expedite your queries, specify the Expedited tier. For more information +// about tiers, see "Restoring Archives," later in this topic. +// - Specify details about the data serialization format of both the input +// object that is being queried and the serialization of the CSV-encoded query +// results. +// +// The following are additional important facts about the select feature: +// - The output results are new Amazon S3 objects. Unlike archive retrievals, +// they are stored until explicitly deleted-manually or through a lifecycle +// configuration. +// - You can issue more than one select request on the same Amazon S3 object. +// Amazon S3 doesn't duplicate requests, so avoid issuing duplicate requests. +// - Amazon S3 accepts a select request even if the object has already been +// restored. A select request doesn’t return error response 409 . +// +// Permissions To use this operation, you must have permissions to perform the +// s3:RestoreObject action. The bucket owner has this permission by default and can +// grant this permission to others. For more information about permissions, see +// Permissions Related to Bucket Subresource Operations (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) +// and Managing Access Permissions to Your Amazon S3 Resources (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) +// in the Amazon S3 User Guide. Restoring objects Objects that you archive to the +// S3 Glacier Flexible Retrieval Flexible Retrieval or S3 Glacier Deep Archive +// storage class, and S3 Intelligent-Tiering Archive or S3 Intelligent-Tiering Deep +// Archive tiers, are not accessible in real time. For objects in the S3 Glacier +// Flexible Retrieval Flexible Retrieval or S3 Glacier Deep Archive storage +// classes, you must first initiate a restore request, and then wait until a +// temporary copy of the object is available. If you want a permanent copy of the +// object, create a copy of it in the Amazon S3 Standard storage class in your S3 +// bucket. To access an archived object, you must restore the object for the +// duration (number of days) that you specify. For objects in the Archive Access or +// Deep Archive Access tiers of S3 Intelligent-Tiering, you must first initiate a // restore request, and then wait until the object is moved into the Frequent -// Access tier. For objects in S3 Glacier or S3 Glacier Deep Archive storage -// classes you must first initiate a restore request, and then wait until a -// temporary copy of the object is available. To access an archived object, you -// must restore the object for the duration (number of days) that you specify. To -// restore a specific object version, you can provide a version ID. If you don't -// provide a version ID, Amazon S3 restores the current version. When restoring an -// archived object (or using a select request), you can specify one of the -// following data access tier options in the Tier element of the request body: -// -// * -// Expedited - Expedited retrievals allow you to quickly access your data stored in -// the S3 Glacier storage class or S3 Intelligent-Tiering Archive tier when -// occasional urgent requests for a subset of archives are required. For all but -// the largest archived objects (250 MB+), data accessed using Expedited retrievals -// is typically made available within 1–5 minutes. Provisioned capacity ensures -// that retrieval capacity for Expedited retrievals is available when you need it. -// Expedited retrievals and provisioned capacity are not available for objects -// stored in the S3 Glacier Deep Archive storage class or S3 Intelligent-Tiering -// Deep Archive tier. -// -// * Standard - Standard retrievals allow you to access any of -// your archived objects within several hours. This is the default option for -// retrieval requests that do not specify the retrieval option. Standard retrievals -// typically finish within 3–5 hours for objects stored in the S3 Glacier storage -// class or S3 Intelligent-Tiering Archive tier. They typically finish within 12 -// hours for objects stored in the S3 Glacier Deep Archive storage class or S3 -// Intelligent-Tiering Deep Archive tier. Standard retrievals are free for objects -// stored in S3 Intelligent-Tiering. -// -// * Bulk - Bulk retrievals are the lowest-cost -// retrieval option in S3 Glacier, enabling you to retrieve large amounts, even -// petabytes, of data inexpensively. Bulk retrievals typically finish within 5–12 -// hours for objects stored in the S3 Glacier storage class or S3 -// Intelligent-Tiering Archive tier. They typically finish within 48 hours for -// objects stored in the S3 Glacier Deep Archive storage class or S3 -// Intelligent-Tiering Deep Archive tier. Bulk retrievals are free for objects -// stored in S3 Intelligent-Tiering. -// -// For more information about archive retrieval -// options and provisioned capacity for Expedited data access, see Restoring -// Archived Objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/restoring-objects.html) in the -// Amazon S3 User Guide. You can use Amazon S3 restore speed upgrade to change the -// restore speed to a faster speed while it is in progress. For more information, -// see Upgrading the speed of an in-progress restore -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/restoring-objects.html#restoring-objects-upgrade-tier.title.html) +// Access tier. To restore a specific object version, you can provide a version ID. +// If you don't provide a version ID, Amazon S3 restores the current version. When +// restoring an archived object, you can specify one of the following data access +// tier options in the Tier element of the request body: +// - Expedited - Expedited retrievals allow you to quickly access your data +// stored in the S3 Glacier Flexible Retrieval Flexible Retrieval storage class or +// S3 Intelligent-Tiering Archive tier when occasional urgent requests for +// restoring archives are required. For all but the largest archived objects (250 +// MB+), data accessed using Expedited retrievals is typically made available +// within 1–5 minutes. Provisioned capacity ensures that retrieval capacity for +// Expedited retrievals is available when you need it. Expedited retrievals and +// provisioned capacity are not available for objects stored in the S3 Glacier Deep +// Archive storage class or S3 Intelligent-Tiering Deep Archive tier. +// - Standard - Standard retrievals allow you to access any of your archived +// objects within several hours. This is the default option for retrieval requests +// that do not specify the retrieval option. Standard retrievals typically finish +// within 3–5 hours for objects stored in the S3 Glacier Flexible Retrieval +// Flexible Retrieval storage class or S3 Intelligent-Tiering Archive tier. They +// typically finish within 12 hours for objects stored in the S3 Glacier Deep +// Archive storage class or S3 Intelligent-Tiering Deep Archive tier. Standard +// retrievals are free for objects stored in S3 Intelligent-Tiering. +// - Bulk - Bulk retrievals free for objects stored in the S3 Glacier Flexible +// Retrieval and S3 Intelligent-Tiering storage classes, enabling you to retrieve +// large amounts, even petabytes, of data at no cost. Bulk retrievals typically +// finish within 5–12 hours for objects stored in the S3 Glacier Flexible Retrieval +// Flexible Retrieval storage class or S3 Intelligent-Tiering Archive tier. Bulk +// retrievals are also the lowest-cost retrieval option when restoring objects from +// S3 Glacier Deep Archive. They typically finish within 48 hours for objects +// stored in the S3 Glacier Deep Archive storage class or S3 Intelligent-Tiering +// Deep Archive tier. +// +// For more information about archive retrieval options and provisioned capacity +// for Expedited data access, see Restoring Archived Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/restoring-objects.html) +// in the Amazon S3 User Guide. You can use Amazon S3 restore speed upgrade to +// change the restore speed to a faster speed while it is in progress. For more +// information, see Upgrading the speed of an in-progress restore (https://docs.aws.amazon.com/AmazonS3/latest/dev/restoring-objects.html#restoring-objects-upgrade-tier.title.html) // in the Amazon S3 User Guide. To get the status of object restoration, you can // send a HEAD request. Operations return the x-amz-restore header, which provides // information about the restoration status, in the response. You can use Amazon S3 // event notifications to notify you when a restore is initiated or completed. For -// more information, see Configuring Amazon S3 Event Notifications -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) in the -// Amazon S3 User Guide. After restoring an archived object, you can update the -// restoration period by reissuing the request with a new period. Amazon S3 updates -// the restoration period relative to the current time and charges only for the -// request-there are no data transfer charges. You cannot update the restoration -// period when Amazon S3 is actively processing your current restore request for -// the object. If your bucket has a lifecycle configuration with a rule that -// includes an expiration action, the object expiration overrides the life span -// that you specify in a restore request. For example, if you restore an object -// copy for 10 days, but the object is scheduled to expire in 3 days, Amazon S3 -// deletes the object in 3 days. For more information about lifecycle -// configuration, see PutBucketLifecycleConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html) -// and Object Lifecycle Management -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html) in -// Amazon S3 User Guide. Responses A successful action returns either the 200 OK or -// 202 Accepted status code. -// -// * If the object is not previously restored, then -// Amazon S3 returns 202 Accepted in the response. +// more information, see Configuring Amazon S3 Event Notifications (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) +// in the Amazon S3 User Guide. After restoring an archived object, you can update +// the restoration period by reissuing the request with a new period. Amazon S3 +// updates the restoration period relative to the current time and charges only for +// the request-there are no data transfer charges. You cannot update the +// restoration period when Amazon S3 is actively processing your current restore +// request for the object. If your bucket has a lifecycle configuration with a rule +// that includes an expiration action, the object expiration overrides the life +// span that you specify in a restore request. For example, if you restore an +// object copy for 10 days, but the object is scheduled to expire in 3 days, Amazon +// S3 deletes the object in 3 days. For more information about lifecycle +// configuration, see PutBucketLifecycleConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html) +// and Object Lifecycle Management (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html) +// in Amazon S3 User Guide. Responses A successful action returns either the 200 OK +// or 202 Accepted status code. // -// * If the object is previously -// restored, Amazon S3 returns 200 OK in the response. +// - If the object is not previously restored, then Amazon S3 returns 202 +// Accepted in the response. // -// # Special Errors +// - If the object is previously restored, Amazon S3 returns 200 OK in the +// response. // -// * Code: -// RestoreAlreadyInProgress +// - Special errors: // -// * Cause: Object restore is already in progress. (This -// error does not apply to SELECT type requests.) +// - Code: RestoreAlreadyInProgress // -// * HTTP Status Code: 409 -// Conflict +// - Cause: Object restore is already in progress. (This error does not apply to +// SELECT type requests.) // -// * SOAP Fault Code Prefix: Client +// - HTTP Status Code: 409 Conflict // -// * Code: -// GlacierExpeditedRetrievalNotAvailable +// - SOAP Fault Code Prefix: Client // -// * Cause: expedited retrievals are -// currently not available. Try again later. (Returned if there is insufficient -// capacity to process the Expedited request. This error applies only to Expedited -// retrievals and not to S3 Standard or Bulk retrievals.) +// - Code: GlacierExpeditedRetrievalNotAvailable // -// * HTTP Status Code: -// 503 +// - Cause: expedited retrievals are currently not available. Try again later. +// (Returned if there is insufficient capacity to process the Expedited request. +// This error applies only to Expedited retrievals and not to S3 Standard or Bulk +// retrievals.) // -// * SOAP Fault Code Prefix: N/A +// - HTTP Status Code: 503 // -// # Related Resources +// - SOAP Fault Code Prefix: N/A // -// * -// PutBucketLifecycleConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html) -// -// * -// GetBucketNotificationConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketNotificationConfiguration.html) -// -// * -// SQL Reference for Amazon S3 Select and S3 Glacier Select -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/s3-glacier-select-sql-reference.html) -// in the Amazon S3 User Guide +// The following operations are related to RestoreObject : +// - PutBucketLifecycleConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html) +// - GetBucketNotificationConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketNotificationConfiguration.html) func (c *Client) RestoreObject(ctx context.Context, params *RestoreObjectInput, optFns ...func(*Options)) (*RestoreObjectOutput, error) { if params == nil { params = &RestoreObjectInput{} @@ -248,23 +184,21 @@ func (c *Client) RestoreObject(ctx context.Context, params *RestoreObjectInput, type RestoreObjectInput struct { - // The bucket name containing the object to restore. When using this action with an - // access point, you must direct requests to the access point hostname. The access - // point hostname takes the form + // The bucket name containing the object to restore. When using this action with + // an access point, you must direct requests to the access point hostname. The + // access point hostname takes the form // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -278,9 +212,8 @@ type RestoreObjectInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. ChecksumAlgorithm types.ChecksumAlgorithm @@ -291,10 +224,11 @@ type RestoreObjectInput struct { ExpectedBucketOwner *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -332,6 +266,9 @@ func (c *Client) addOperationRestoreObjectMiddlewares(stack *middleware.Stack, o if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -359,7 +296,7 @@ func (c *Client) addOperationRestoreObjectMiddlewares(stack *middleware.Stack, o if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -371,6 +308,9 @@ func (c *Client) addOperationRestoreObjectMiddlewares(stack *middleware.Stack, o if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addRestoreObjectResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpRestoreObjectValidationMiddleware(stack); err != nil { return err } @@ -380,6 +320,9 @@ func (c *Client) addOperationRestoreObjectMiddlewares(stack *middleware.Stack, o if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addRestoreObjectInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -398,9 +341,22 @@ func (c *Client) addOperationRestoreObjectMiddlewares(stack *middleware.Stack, o if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *RestoreObjectInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opRestoreObject(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -410,8 +366,8 @@ func newServiceMetadataMiddleware_opRestoreObject(region string) *awsmiddleware. } } -// getRestoreObjectRequestAlgorithmMember gets the request checksum algorithm value -// provided as input. +// getRestoreObjectRequestAlgorithmMember gets the request checksum algorithm +// value provided as input. func getRestoreObjectRequestAlgorithmMember(input interface{}) (string, bool) { in := input.(*RestoreObjectInput) if len(in.ChecksumAlgorithm) == 0 { @@ -455,3 +411,139 @@ func addRestoreObjectUpdateEndpoint(stack *middleware.Stack, options Options) er DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opRestoreObjectResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opRestoreObjectResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opRestoreObjectResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*RestoreObjectInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addRestoreObjectResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opRestoreObjectResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_SelectObjectContent.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_SelectObjectContent.go index 1b9dbc7bc..d6c2ff637 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_SelectObjectContent.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_SelectObjectContent.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithysync "github.com/aws/smithy-go/sync" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -21,86 +27,58 @@ import ( // into records, and returns only records that match the specified SQL expression. // You must also specify the data serialization format for the response. This // action is not supported by Amazon S3 on Outposts. For more information about -// Amazon S3 Select, see Selecting Content from Objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/selecting-content-from-objects.html) -// and SELECT Command -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-glacier-select-sql-reference-select.html) -// in the Amazon S3 User Guide. For more information about using SQL with Amazon S3 -// Select, see SQL Reference for Amazon S3 Select and S3 Glacier Select -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/s3-glacier-select-sql-reference.html) +// Amazon S3 Select, see Selecting Content from Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/selecting-content-from-objects.html) +// and SELECT Command (https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-glacier-select-sql-reference-select.html) // in the Amazon S3 User Guide. Permissions You must have s3:GetObject permission // for this operation. Amazon S3 Select does not support anonymous access. For more -// information about permissions, see Specifying Permissions in a Policy -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html) in -// the Amazon S3 User Guide. Object Data Formats You can use Amazon S3 Select to +// information about permissions, see Specifying Permissions in a Policy (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html) +// in the Amazon S3 User Guide. Object Data Formats You can use Amazon S3 Select to // query objects that have the following format properties: +// - CSV, JSON, and Parquet - Objects must be in CSV, JSON, or Parquet format. +// - UTF-8 - UTF-8 is the only encoding type Amazon S3 Select supports. +// - GZIP or BZIP2 - CSV and JSON files can be compressed using GZIP or BZIP2. +// GZIP and BZIP2 are the only compression formats that Amazon S3 Select supports +// for CSV and JSON files. Amazon S3 Select supports columnar compression for +// Parquet using GZIP or Snappy. Amazon S3 Select does not support whole-object +// compression for Parquet objects. +// - Server-side encryption - Amazon S3 Select supports querying objects that +// are protected with server-side encryption. For objects that are encrypted with +// customer-provided encryption keys (SSE-C), you must use HTTPS, and you must use +// the headers that are documented in the GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// . For more information about SSE-C, see Server-Side Encryption (Using +// Customer-Provided Encryption Keys) (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) +// in the Amazon S3 User Guide. For objects that are encrypted with Amazon S3 +// managed keys (SSE-S3) and Amazon Web Services KMS keys (SSE-KMS), server-side +// encryption is handled transparently, so you don't need to specify anything. For +// more information about server-side encryption, including SSE-S3 and SSE-KMS, see +// Protecting Data Using Server-Side Encryption (https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html) +// in the Amazon S3 User Guide. // -// * CSV, JSON, and -// Parquet - Objects must be in CSV, JSON, or Parquet format. +// Working with the Response Body Given the response size is unknown, Amazon S3 +// Select streams the response as a series of messages and includes a +// Transfer-Encoding header with chunked as its value in the response. For more +// information, see Appendix: SelectObjectContent Response (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTSelectObjectAppendix.html) +// . GetObject Support The SelectObjectContent action does not support the +// following GetObject functionality. For more information, see GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// . +// - Range : Although you can specify a scan range for an Amazon S3 Select +// request (see SelectObjectContentRequest - ScanRange (https://docs.aws.amazon.com/AmazonS3/latest/API/API_SelectObjectContent.html#AmazonS3-SelectObjectContent-request-ScanRange) +// in the request parameters), you cannot specify the range of bytes of an object +// to return. +// - The GLACIER , DEEP_ARCHIVE , and REDUCED_REDUNDANCY storage classes, or the +// ARCHIVE_ACCESS and DEEP_ARCHIVE_ACCESS access tiers of the INTELLIGENT_TIERING +// storage class: You cannot query objects in the GLACIER , DEEP_ARCHIVE , or +// REDUCED_REDUNDANCY storage classes, nor objects in the ARCHIVE_ACCESS or +// DEEP_ARCHIVE_ACCESS access tiers of the INTELLIGENT_TIERING storage class. For +// more information about storage classes, see Using Amazon S3 storage classes (https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage-class-intro.html) +// in the Amazon S3 User Guide. // -// * UTF-8 - UTF-8 is -// the only encoding type Amazon S3 Select supports. -// -// * GZIP or BZIP2 - CSV and -// JSON files can be compressed using GZIP or BZIP2. GZIP and BZIP2 are the only -// compression formats that Amazon S3 Select supports for CSV and JSON files. -// Amazon S3 Select supports columnar compression for Parquet using GZIP or Snappy. -// Amazon S3 Select does not support whole-object compression for Parquet -// objects. -// -// * Server-side encryption - Amazon S3 Select supports querying objects -// that are protected with server-side encryption. For objects that are encrypted -// with customer-provided encryption keys (SSE-C), you must use HTTPS, and you must -// use the headers that are documented in the GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html). For more -// information about SSE-C, see Server-Side Encryption (Using Customer-Provided -// Encryption Keys) -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) -// in the Amazon S3 User Guide. For objects that are encrypted with Amazon S3 -// managed encryption keys (SSE-S3) and Amazon Web Services KMS keys (SSE-KMS), -// server-side encryption is handled transparently, so you don't need to specify -// anything. For more information about server-side encryption, including SSE-S3 -// and SSE-KMS, see Protecting Data Using Server-Side Encryption -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html) in -// the Amazon S3 User Guide. -// -// Working with the Response Body Given the response -// size is unknown, Amazon S3 Select streams the response as a series of messages -// and includes a Transfer-Encoding header with chunked as its value in the -// response. For more information, see Appendix: SelectObjectContent Response -// (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTSelectObjectAppendix.html). -// GetObject Support The SelectObjectContent action does not support the following -// GetObject functionality. For more information, see GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html). -// -// * Range: -// Although you can specify a scan range for an Amazon S3 Select request (see -// SelectObjectContentRequest - ScanRange -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_SelectObjectContent.html#AmazonS3-SelectObjectContent-request-ScanRange) -// in the request parameters), you cannot specify the range of bytes of an object -// to return. -// -// * GLACIER, DEEP_ARCHIVE and REDUCED_REDUNDANCY storage classes: You -// cannot specify the GLACIER, DEEP_ARCHIVE, or REDUCED_REDUNDANCY storage classes. -// For more information, about storage classes see Storage Classes -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#storage-class-intro) -// in the Amazon S3 User Guide. -// -// Special Errors For a list of special errors for -// this operation, see List of SELECT Object Content Error Codes -// (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#SelectObjectContentErrorCodeList) -// Related Resources -// -// * GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) -// -// * -// GetBucketLifecycleConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html) -// -// * -// PutBucketLifecycleConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html) +// Special Errors For a list of special errors for this operation, see List of +// SELECT Object Content Error Codes (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#SelectObjectContentErrorCodeList) +// The following operations are related to SelectObjectContent : +// - GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// - GetBucketLifecycleConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html) +// - PutBucketLifecycleConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html) func (c *Client) SelectObjectContent(ctx context.Context, params *SelectObjectContentInput, optFns ...func(*Options)) (*SelectObjectContentOutput, error) { if params == nil { params = &SelectObjectContentInput{} @@ -122,8 +100,8 @@ func (c *Client) SelectObjectContent(ctx context.Context, params *SelectObjectCo // object. Amazon S3 uses this to parse object data into records. It returns only // records that match the specified SQL expression. You must also specify the data // serialization format for the response. For more information, see S3Select API -// Documentation -// (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectSELECTContent.html). +// Documentation (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectSELECTContent.html) +// . type SelectObjectContentInput struct { // The S3 bucket. @@ -166,39 +144,31 @@ type SelectObjectContentInput struct { // The server-side encryption (SSE) algorithm used to encrypt the object. This // parameter is needed only when the object was created using a checksum algorithm. - // For more information, see Protecting data using SSE-C keys - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) + // For more information, see Protecting data using SSE-C keys (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) // in the Amazon S3 User Guide. SSECustomerAlgorithm *string // The server-side encryption (SSE) customer managed key. This parameter is needed // only when the object was created using a checksum algorithm. For more - // information, see Protecting data using SSE-C keys - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) + // information, see Protecting data using SSE-C keys (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) // in the Amazon S3 User Guide. SSECustomerKey *string // The MD5 server-side encryption (SSE) customer managed key. This parameter is // needed only when the object was created using a checksum algorithm. For more - // information, see Protecting data using SSE-C keys - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) + // information, see Protecting data using SSE-C keys (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html) // in the Amazon S3 User Guide. SSECustomerKeyMD5 *string // Specifies the byte range of the object to get the records from. A record is // processed when its first byte is contained by the range. This parameter is // optional, but when specified, it must not be empty. See RFC 2616, Section - // 14.35.1 about how to specify the start and end of the range. ScanRangemay be + // 14.35.1 about how to specify the start and end of the range. ScanRange may be // used in the following ways: - // - // * 50100 - process only the records starting between - // the bytes 50 and 100 (inclusive, counting from zero) - // - // * 50 - process only the - // records starting after the byte 50 - // - // * 50 - process only the records within the - // last 50 bytes of the file. + // - 50100 - process only the records starting between the bytes 50 and 100 + // (inclusive, counting from zero) + // - 50 - process only the records starting after the byte 50 + // - 50 - process only the records within the last 50 bytes of the file. ScanRange *types.ScanRange noSmithyDocumentSerde @@ -227,6 +197,9 @@ func (c *Client) addOperationSelectObjectContentMiddlewares(stack *middleware.St if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addEventStreamSelectObjectContentMiddleware(stack, options); err != nil { return err } @@ -257,12 +230,15 @@ func (c *Client) addOperationSelectObjectContentMiddlewares(stack *middleware.St if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addSelectObjectContentResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpSelectObjectContentValidationMiddleware(stack); err != nil { return err } @@ -272,6 +248,9 @@ func (c *Client) addOperationSelectObjectContentMiddlewares(stack *middleware.St if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addSelectObjectContentUpdateEndpoint(stack, options); err != nil { return err } @@ -287,9 +266,22 @@ func (c *Client) addOperationSelectObjectContentMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *SelectObjectContentInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opSelectObjectContent(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -424,3 +416,139 @@ func (es *SelectObjectContentEventStream) waitStreamClose() { } } + +type opSelectObjectContentResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opSelectObjectContentResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opSelectObjectContentResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*SelectObjectContentInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addSelectObjectContentResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opSelectObjectContentResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_UploadPart.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_UploadPart.go index 2617bed60..a3e1a7db4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_UploadPart.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_UploadPart.go @@ -4,12 +4,18 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" internalChecksum "github.com/aws/aws-sdk-go-v2/service/internal/checksum" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "io" @@ -18,101 +24,74 @@ import ( // Uploads a part in a multipart upload. In this operation, you provide part data // in your request. However, you have an option to specify your existing Amazon S3 // object as a data source for the part you are uploading. To upload a part from an -// existing object, you use the UploadPartCopy -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) -// operation. You must initiate a multipart upload (see CreateMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html)) -// before you can upload any part. In response to your initiate request, Amazon S3 -// returns an upload ID, a unique identifier, that you must include in your upload -// part request. Part numbers can be any number from 1 to 10,000, inclusive. A part -// number uniquely identifies a part and also defines its position within the -// object being created. If you upload a new part using the same part number that -// was used with a previous part, the previously uploaded part is overwritten. For -// information about maximum and minimum part sizes and other multipart upload -// specifications, see Multipart upload limits -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts.html) in the -// Amazon S3 User Guide. To ensure that data is not corrupted when traversing the -// network, specify the Content-MD5 header in the upload part request. Amazon S3 -// checks the part data against the provided MD5 value. If they do not match, -// Amazon S3 returns an error. If the upload request is signed with Signature -// Version 4, then Amazon Web Services S3 uses the x-amz-content-sha256 header as a -// checksum instead of Content-MD5. For more information see Authenticating -// Requests: Using the Authorization Header (Amazon Web Services Signature Version -// 4) -// (https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html). -// Note: After you initiate multipart upload and upload one or more parts, you must -// either complete or abort multipart upload in order to stop getting charged for -// storage of the uploaded parts. Only after you either complete or abort multipart -// upload, Amazon S3 frees up the parts storage and stops charging you for the -// parts storage. For more information on multipart uploads, go to Multipart Upload -// Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html) in -// the Amazon S3 User Guide . For information on the permissions required to use -// the multipart upload API, go to Multipart Upload and Permissions -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html) in the -// Amazon S3 User Guide. You can optionally request server-side encryption where -// Amazon S3 encrypts your data as it writes it to disks in its data centers and -// decrypts it for you when you access it. You have the option of providing your -// own encryption key, or you can use the Amazon Web Services managed encryption -// keys. If you choose to provide your own encryption key, the request headers you -// provide in the request must match the headers you used in the request to -// initiate the upload by using CreateMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html). -// For more information, go to Using Server-Side Encryption -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html) +// existing object, you use the UploadPartCopy (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) +// operation. You must initiate a multipart upload (see CreateMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) +// ) before you can upload any part. In response to your initiate request, Amazon +// S3 returns an upload ID, a unique identifier, that you must include in your +// upload part request. Part numbers can be any number from 1 to 10,000, inclusive. +// A part number uniquely identifies a part and also defines its position within +// the object being created. If you upload a new part using the same part number +// that was used with a previous part, the previously uploaded part is overwritten. +// For information about maximum and minimum part sizes and other multipart upload +// specifications, see Multipart upload limits (https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts.html) +// in the Amazon S3 User Guide. To ensure that data is not corrupted when +// traversing the network, specify the Content-MD5 header in the upload part +// request. Amazon S3 checks the part data against the provided MD5 value. If they +// do not match, Amazon S3 returns an error. If the upload request is signed with +// Signature Version 4, then Amazon Web Services S3 uses the x-amz-content-sha256 +// header as a checksum instead of Content-MD5 . For more information see +// Authenticating Requests: Using the Authorization Header (Amazon Web Services +// Signature Version 4) (https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html) +// . Note: After you initiate multipart upload and upload one or more parts, you +// must either complete or abort multipart upload in order to stop getting charged +// for storage of the uploaded parts. Only after you either complete or abort +// multipart upload, Amazon S3 frees up the parts storage and stops charging you +// for the parts storage. For more information on multipart uploads, go to +// Multipart Upload Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html) +// in the Amazon S3 User Guide . For information on the permissions required to use +// the multipart upload API, go to Multipart Upload and Permissions (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html) +// in the Amazon S3 User Guide. Server-side encryption is for data encryption at +// rest. Amazon S3 encrypts your data as it writes it to disks in its data centers +// and decrypts it when you access it. You have three mutually exclusive options to +// protect data using server-side encryption in Amazon S3, depending on how you +// choose to manage the encryption keys. Specifically, the encryption key options +// are Amazon S3 managed keys (SSE-S3), Amazon Web Services KMS keys (SSE-KMS), and +// Customer-Provided Keys (SSE-C). Amazon S3 encrypts data with server-side +// encryption using Amazon S3 managed keys (SSE-S3) by default. You can optionally +// tell Amazon S3 to encrypt data at rest using server-side encryption with other +// key options. The option you use depends on whether you want to use KMS keys +// (SSE-KMS) or provide your own encryption key (SSE-C). If you choose to provide +// your own encryption key, the request headers you provide in the request must +// match the headers you used in the request to initiate the upload by using +// CreateMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) +// . For more information, go to Using Server-Side Encryption (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html) // in the Amazon S3 User Guide. Server-side encryption is supported by the S3 // Multipart Upload actions. Unless you are using a customer-provided encryption -// key, you don't need to specify the encryption parameters in each UploadPart -// request. Instead, you only need to specify the server-side encryption parameters -// in the initial Initiate Multipart request. For more information, see -// CreateMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html). -// If you requested server-side encryption using a customer-provided encryption key -// in your initiate multipart upload request, you must provide identical encryption -// information in each part upload using the following headers. +// key (SSE-C), you don't need to specify the encryption parameters in each +// UploadPart request. Instead, you only need to specify the server-side encryption +// parameters in the initial Initiate Multipart request. For more information, see +// CreateMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) +// . If you requested server-side encryption using a customer-provided encryption +// key (SSE-C) in your initiate multipart upload request, you must provide +// identical encryption information in each part upload using the following +// headers. +// - x-amz-server-side-encryption-customer-algorithm +// - x-amz-server-side-encryption-customer-key +// - x-amz-server-side-encryption-customer-key-MD5 // -// * -// x-amz-server-side-encryption-customer-algorithm +// UploadPart has the following special errors: +// - Code: NoSuchUpload +// - Cause: The specified multipart upload does not exist. The upload ID might +// be invalid, or the multipart upload might have been aborted or completed. +// - HTTP Status Code: 404 Not Found +// - SOAP Fault Code Prefix: Client // -// * -// x-amz-server-side-encryption-customer-key -// -// * -// x-amz-server-side-encryption-customer-key-MD5 -// -// # Special Errors -// -// * Code: -// NoSuchUpload -// -// * Cause: The specified multipart upload does not exist. The upload -// ID might be invalid, or the multipart upload might have been aborted or -// completed. -// -// * HTTP Status Code: 404 Not Found -// -// * SOAP Fault Code Prefix: -// Client -// -// # Related Resources -// -// * CreateMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) -// -// * -// CompleteMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) -// -// * -// AbortMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) -// -// * -// ListParts -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) -// -// * -// ListMultipartUploads -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) +// The following operations are related to UploadPart : +// - CreateMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) +// - CompleteMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) +// - AbortMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) +// - ListParts (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) +// - ListMultipartUploads (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) func (c *Client) UploadPart(ctx context.Context, params *UploadPartInput, optFns ...func(*Options)) (*UploadPartOutput, error) { if params == nil { params = &UploadPartInput{} @@ -136,17 +115,15 @@ type UploadPartInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string @@ -174,9 +151,8 @@ type UploadPartInput struct { // the SDK. This header will not provide any additional functionality if not using // the SDK. When sending this header, there must be a corresponding x-amz-checksum // or x-amz-trailer header sent. Otherwise, Amazon S3 fails the request with the - // HTTP status code 400 Bad Request. For more information, see Checking object - // integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // HTTP status code 400 Bad Request . For more information, see Checking object + // integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. If you provide an individual checksum, Amazon S3 // ignores any provided ChecksumAlgorithm parameter. This checksum algorithm must // be the same for all parts and it match the checksum value supplied in the @@ -186,32 +162,28 @@ type UploadPartInput struct { // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 32-bit CRC32 checksum of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumCRC32 *string // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 32-bit CRC32C checksum of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumCRC32C *string // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 160-bit SHA-1 digest of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumSHA1 *string // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 256-bit SHA-256 digest of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumSHA256 *string @@ -230,10 +202,11 @@ type UploadPartInput struct { ExpectedBucketOwner *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -245,7 +218,7 @@ type UploadPartInput struct { // encrypting data. This value is used to store the object and then it is // discarded; Amazon S3 does not store the encryption key. The key must be // appropriate for use with the algorithm specified in the - // x-amz-server-side-encryption-customer-algorithm header. This must be the same + // x-amz-server-side-encryption-customer-algorithm header . This must be the same // encryption key specified in the initiate multipart upload request. SSECustomerKey *string @@ -260,38 +233,34 @@ type UploadPartInput struct { type UploadPartOutput struct { // Indicates whether the multipart upload uses an S3 Bucket Key for server-side - // encryption with Amazon Web Services KMS (SSE-KMS). + // encryption with Key Management Service (KMS) keys (SSE-KMS). BucketKeyEnabled bool // The base64-encoded, 32-bit CRC32 checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32 *string // The base64-encoded, 32-bit CRC32C checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32C *string // The base64-encoded, 160-bit SHA-1 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA1 *string // The base64-encoded, 256-bit SHA-256 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA256 *string @@ -302,22 +271,22 @@ type UploadPartOutput struct { // request. RequestCharged types.RequestCharged - // If server-side encryption with a customer-provided encryption key was requested, - // the response will include this header confirming the encryption algorithm used. + // If server-side encryption with a customer-provided encryption key was + // requested, the response will include this header confirming the encryption + // algorithm used. SSECustomerAlgorithm *string - // If server-side encryption with a customer-provided encryption key was requested, - // the response will include this header to provide round-trip message integrity - // verification of the customer-provided encryption key. + // If server-side encryption with a customer-provided encryption key was + // requested, the response will include this header to provide round-trip message + // integrity verification of the customer-provided encryption key. SSECustomerKeyMD5 *string - // If present, specifies the ID of the Amazon Web Services Key Management Service - // (Amazon Web Services KMS) symmetric customer managed key was used for the - // object. + // If present, specifies the ID of the Key Management Service (KMS) symmetric + // encryption customer managed key was used for the object. SSEKMSKeyId *string // The server-side encryption algorithm used when storing this object in Amazon S3 - // (for example, AES256, aws:kms). + // (for example, AES256 , aws:kms ). ServerSideEncryption types.ServerSideEncryption // Metadata pertaining to the operation's result. @@ -335,6 +304,9 @@ func (c *Client) addOperationUploadPartMiddlewares(stack *middleware.Stack, opti if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -362,7 +334,7 @@ func (c *Client) addOperationUploadPartMiddlewares(stack *middleware.Stack, opti if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -374,6 +346,9 @@ func (c *Client) addOperationUploadPartMiddlewares(stack *middleware.Stack, opti if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addUploadPartResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpUploadPartValidationMiddleware(stack); err != nil { return err } @@ -383,6 +358,12 @@ func (c *Client) addOperationUploadPartMiddlewares(stack *middleware.Stack, opti if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = add100Continue(stack, options); err != nil { + return err + } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addUploadPartInputChecksumMiddlewares(stack, options); err != nil { return err } @@ -404,9 +385,22 @@ func (c *Client) addOperationUploadPartMiddlewares(stack *middleware.Stack, opti if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *UploadPartInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opUploadPart(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -436,8 +430,9 @@ func addUploadPartInputChecksumMiddlewares(stack *middleware.Stack, options Opti }) } -// getUploadPartBucketMember returns a pointer to string denoting a provided bucket -// member valueand a boolean indicating if the input has a modeled bucket name, +// getUploadPartBucketMember returns a pointer to string denoting a provided +// bucket member valueand a boolean indicating if the input has a modeled bucket +// name, func getUploadPartBucketMember(input interface{}) (*string, bool) { in := input.(*UploadPartInput) if in.Bucket == nil { @@ -494,3 +489,139 @@ func addUploadPartPayloadAsUnsigned(stack *middleware.Stack, options Options) er v4.RemoveComputePayloadSHA256Middleware(stack) return v4.AddUnsignedPayloadMiddleware(stack) } + +type opUploadPartResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opUploadPartResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opUploadPartResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*UploadPartInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addUploadPartResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opUploadPartResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_UploadPartCopy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_UploadPartCopy.go index f1fa13954..ce9a179a7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_UploadPartCopy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_UploadPartCopy.go @@ -4,10 +4,16 @@ package s3 import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "time" @@ -15,112 +21,72 @@ import ( // Uploads a part by copying data from an existing object as data source. You // specify the data source by adding the request header x-amz-copy-source in your -// request and a byte range by adding the request header x-amz-copy-source-range in -// your request. For information about maximum and minimum part sizes and other -// multipart upload specifications, see Multipart upload limits -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts.html) in the -// Amazon S3 User Guide. Instead of using an existing object as part data, you -// might use the UploadPart -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) action and -// provide data in your request. You must initiate a multipart upload before you -// can upload any part. In response to your initiate request. Amazon S3 returns a -// unique identifier, the upload ID, that you must include in your upload part -// request. For more information about using the UploadPartCopy operation, see the -// following: +// request and a byte range by adding the request header x-amz-copy-source-range +// in your request. For information about maximum and minimum part sizes and other +// multipart upload specifications, see Multipart upload limits (https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts.html) +// in the Amazon S3 User Guide. Instead of using an existing object as part data, +// you might use the UploadPart (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) +// action and provide data in your request. You must initiate a multipart upload +// before you can upload any part. In response to your initiate request. Amazon S3 +// returns a unique identifier, the upload ID, that you must include in your upload +// part request. For more information about using the UploadPartCopy operation, +// see the following: +// - For conceptual information about multipart uploads, see Uploading Objects +// Using Multipart Upload (https://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html) +// in the Amazon S3 User Guide. +// - For information about permissions required to use the multipart upload API, +// see Multipart Upload and Permissions (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html) +// in the Amazon S3 User Guide. +// - For information about copying objects using a single atomic action vs. a +// multipart upload, see Operations on Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectOperations.html) +// in the Amazon S3 User Guide. +// - For information about using server-side encryption with customer-provided +// encryption keys with the UploadPartCopy operation, see CopyObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) +// and UploadPart (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) +// . // -// * For conceptual information about multipart uploads, see Uploading -// Objects Using Multipart Upload -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html) in the -// Amazon S3 User Guide. +// Note the following additional considerations about the request headers +// x-amz-copy-source-if-match , x-amz-copy-source-if-none-match , +// x-amz-copy-source-if-unmodified-since , and x-amz-copy-source-if-modified-since +// : +// - Consideration 1 - If both of the x-amz-copy-source-if-match and +// x-amz-copy-source-if-unmodified-since headers are present in the request as +// follows: x-amz-copy-source-if-match condition evaluates to true , and; +// x-amz-copy-source-if-unmodified-since condition evaluates to false ; Amazon S3 +// returns 200 OK and copies the data. +// - Consideration 2 - If both of the x-amz-copy-source-if-none-match and +// x-amz-copy-source-if-modified-since headers are present in the request as +// follows: x-amz-copy-source-if-none-match condition evaluates to false , and; +// x-amz-copy-source-if-modified-since condition evaluates to true ; Amazon S3 +// returns 412 Precondition Failed response code. // -// * For information about permissions required to use the -// multipart upload API, see Multipart Upload and Permissions -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html) in the -// Amazon S3 User Guide. +// Versioning If your bucket has versioning enabled, you could have multiple +// versions of the same object. By default, x-amz-copy-source identifies the +// current version of the object to copy. If the current version is a delete marker +// and you don't specify a versionId in the x-amz-copy-source , Amazon S3 returns a +// 404 error, because the object does not exist. If you specify versionId in the +// x-amz-copy-source and the versionId is a delete marker, Amazon S3 returns an +// HTTP 400 error, because you are not allowed to specify a delete marker as a +// version for the x-amz-copy-source . You can optionally specify a specific +// version of the source object to copy by adding the versionId subresource as +// shown in the following example: x-amz-copy-source: +// /bucket/object?versionId=version id Special errors +// - Code: NoSuchUpload +// - Cause: The specified multipart upload does not exist. The upload ID might +// be invalid, or the multipart upload might have been aborted or completed. +// - HTTP Status Code: 404 Not Found +// - Code: InvalidRequest +// - Cause: The specified copy source is not supported as a byte-range copy +// source. +// - HTTP Status Code: 400 Bad Request // -// * For information about copying objects using a single -// atomic action vs. a multipart upload, see Operations on Objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectOperations.html) in the -// Amazon S3 User Guide. -// -// * For information about using server-side encryption with -// customer-provided encryption keys with the UploadPartCopy operation, see -// CopyObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html) -// and UploadPart -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html). -// -// Note the -// following additional considerations about the request headers -// x-amz-copy-source-if-match, x-amz-copy-source-if-none-match, -// x-amz-copy-source-if-unmodified-since, and -// x-amz-copy-source-if-modified-since: -// -// * Consideration 1 - If both of the -// x-amz-copy-source-if-match and x-amz-copy-source-if-unmodified-since headers are -// present in the request as follows: x-amz-copy-source-if-match condition -// evaluates to true, and; x-amz-copy-source-if-unmodified-since condition -// evaluates to false; Amazon S3 returns 200 OK and copies the data. -// -// * -// Consideration 2 - If both of the x-amz-copy-source-if-none-match and -// x-amz-copy-source-if-modified-since headers are present in the request as -// follows: x-amz-copy-source-if-none-match condition evaluates to false, and; -// x-amz-copy-source-if-modified-since condition evaluates to true; Amazon S3 -// returns 412 Precondition Failed response code. -// -// Versioning If your bucket has -// versioning enabled, you could have multiple versions of the same object. By -// default, x-amz-copy-source identifies the current version of the object to copy. -// If the current version is a delete marker and you don't specify a versionId in -// the x-amz-copy-source, Amazon S3 returns a 404 error, because the object does -// not exist. If you specify versionId in the x-amz-copy-source and the versionId -// is a delete marker, Amazon S3 returns an HTTP 400 error, because you are not -// allowed to specify a delete marker as a version for the x-amz-copy-source. You -// can optionally specify a specific version of the source object to copy by adding -// the versionId subresource as shown in the following example: x-amz-copy-source: -// /bucket/object?versionId=version id Special Errors -// -// * Code: NoSuchUpload -// -// * -// Cause: The specified multipart upload does not exist. The upload ID might be -// invalid, or the multipart upload might have been aborted or completed. -// -// * HTTP -// Status Code: 404 Not Found -// -// * Code: InvalidRequest -// -// * Cause: The specified copy -// source is not supported as a byte-range copy source. -// -// * HTTP Status Code: 400 -// Bad Request -// -// # Related Resources -// -// * CreateMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) -// -// * -// UploadPart -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) -// -// * -// CompleteMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) -// -// * -// AbortMultipartUpload -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) -// -// * -// ListParts -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) -// -// * -// ListMultipartUploads -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) +// The following operations are related to UploadPartCopy : +// - CreateMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) +// - UploadPart (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) +// - CompleteMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) +// - AbortMultipartUpload (https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) +// - ListParts (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) +// - ListMultipartUploads (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html) func (c *Client) UploadPartCopy(ctx context.Context, params *UploadPartCopyInput, optFns ...func(*Options)) (*UploadPartCopyOutput, error) { if params == nil { params = &UploadPartCopyInput{} @@ -143,53 +109,47 @@ type UploadPartCopyInput struct { // AccessPointName-AccountId.s3-accesspoint.Region.amazonaws.com. When using this // action with an access point through the Amazon Web Services SDKs, you provide // the access point ARN in place of the bucket name. For more information about - // access point ARNs, see Using access points - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) - // in the Amazon S3 User Guide. When using this action with Amazon S3 on Outposts, - // you must direct requests to the S3 on Outposts hostname. The S3 on Outposts - // hostname takes the form - // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com. When using - // this action with S3 on Outposts through the Amazon Web Services SDKs, you - // provide the Outposts bucket ARN in place of the bucket name. For more - // information about S3 on Outposts ARNs, see Using Amazon S3 on Outposts - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) in the - // Amazon S3 User Guide. + // access point ARNs, see Using access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html) + // in the Amazon S3 User Guide. When you use this action with Amazon S3 on + // Outposts, you must direct requests to the S3 on Outposts hostname. The S3 on + // Outposts hostname takes the form + // AccessPointName-AccountId.outpostID.s3-outposts.Region.amazonaws.com . When you + // use this action with S3 on Outposts through the Amazon Web Services SDKs, you + // provide the Outposts access point ARN in place of the bucket name. For more + // information about S3 on Outposts ARNs, see What is S3 on Outposts? (https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html) + // in the Amazon S3 User Guide. // // This member is required. Bucket *string - // Specifies the source object for the copy operation. You specify the value in one - // of two formats, depending on whether you want to access the source object - // through an access point - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-points.html): - // - // * - // For objects not accessed through an access point, specify the name of the source - // bucket and key of the source object, separated by a slash (/). For example, to - // copy the object reports/january.pdf from the bucket awsexamplebucket, use - // awsexamplebucket/reports/january.pdf. The value must be URL-encoded. - // - // * For - // objects accessed through access points, specify the Amazon Resource Name (ARN) - // of the object as accessed through the access point, in the format - // arn:aws:s3:::accesspoint//object/. For example, to copy the object - // reports/january.pdf through access point my-access-point owned by account - // 123456789012 in Region us-west-2, use the URL encoding of - // arn:aws:s3:us-west-2:123456789012:accesspoint/my-access-point/object/reports/january.pdf. - // The value must be URL encoded. Amazon S3 supports copy operations using access - // points only when the source and destination buckets are in the same Amazon Web - // Services Region. Alternatively, for objects accessed through Amazon S3 on - // Outposts, specify the ARN of the object as accessed in the format - // arn:aws:s3-outposts:::outpost//object/. For example, to copy the object - // reports/january.pdf through outpost my-outpost owned by account 123456789012 in - // Region us-west-2, use the URL encoding of - // arn:aws:s3-outposts:us-west-2:123456789012:outpost/my-outpost/object/reports/january.pdf. - // The value must be URL-encoded. - // - // To copy a specific version of an object, append - // ?versionId= to the value (for example, - // awsexamplebucket/reports/january.pdf?versionId=QUpfdndhfd8438MNFDN93jdnJFkdmqnh893). - // If you don't specify a version ID, Amazon S3 copies the latest version of the + // Specifies the source object for the copy operation. You specify the value in + // one of two formats, depending on whether you want to access the source object + // through an access point (https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-points.html) + // : + // - For objects not accessed through an access point, specify the name of the + // source bucket and key of the source object, separated by a slash (/). For + // example, to copy the object reports/january.pdf from the bucket + // awsexamplebucket , use awsexamplebucket/reports/january.pdf . The value must + // be URL-encoded. + // - For objects accessed through access points, specify the Amazon Resource + // Name (ARN) of the object as accessed through the access point, in the format + // arn:aws:s3:::accesspoint//object/ . For example, to copy the object + // reports/january.pdf through access point my-access-point owned by account + // 123456789012 in Region us-west-2 , use the URL encoding of + // arn:aws:s3:us-west-2:123456789012:accesspoint/my-access-point/object/reports/january.pdf + // . The value must be URL encoded. Amazon S3 supports copy operations using access + // points only when the source and destination buckets are in the same Amazon Web + // Services Region. Alternatively, for objects accessed through Amazon S3 on + // Outposts, specify the ARN of the object as accessed in the format + // arn:aws:s3-outposts:::outpost//object/ . For example, to copy the object + // reports/january.pdf through outpost my-outpost owned by account 123456789012 + // in Region us-west-2 , use the URL encoding of + // arn:aws:s3-outposts:us-west-2:123456789012:outpost/my-outpost/object/reports/january.pdf + // . The value must be URL-encoded. + // To copy a specific version of an object, append ?versionId= to the value (for + // example, + // awsexamplebucket/reports/january.pdf?versionId=QUpfdndhfd8438MNFDN93jdnJFkdmqnh893 + // ). If you don't specify a version ID, Amazon S3 copies the latest version of the // source object. // // This member is required. @@ -255,10 +215,11 @@ type UploadPartCopyInput struct { ExpectedSourceBucketOwner *string // Confirms that the requester knows that they will be charged for the request. - // Bucket owners need not specify this parameter in their requests. For information - // about downloading objects from Requester Pays buckets, see Downloading Objects - // in Requester Pays Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) + // Bucket owners need not specify this parameter in their requests. If either the + // source or destination Amazon S3 bucket has Requester Pays enabled, the requester + // will pay for corresponding charges to copy the object. For information about + // downloading objects from Requester Pays buckets, see Downloading Objects in + // Requester Pays Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html) // in the Amazon S3 User Guide. RequestPayer types.RequestPayer @@ -285,36 +246,36 @@ type UploadPartCopyInput struct { type UploadPartCopyOutput struct { // Indicates whether the multipart upload uses an S3 Bucket Key for server-side - // encryption with Amazon Web Services KMS (SSE-KMS). + // encryption with Key Management Service (KMS) keys (SSE-KMS). BucketKeyEnabled bool // Container for all response elements. CopyPartResult *types.CopyPartResult - // The version of the source object that was copied, if you have enabled versioning - // on the source bucket. + // The version of the source object that was copied, if you have enabled + // versioning on the source bucket. CopySourceVersionId *string // If present, indicates that the requester was successfully charged for the // request. RequestCharged types.RequestCharged - // If server-side encryption with a customer-provided encryption key was requested, - // the response will include this header confirming the encryption algorithm used. + // If server-side encryption with a customer-provided encryption key was + // requested, the response will include this header confirming the encryption + // algorithm used. SSECustomerAlgorithm *string - // If server-side encryption with a customer-provided encryption key was requested, - // the response will include this header to provide round-trip message integrity - // verification of the customer-provided encryption key. + // If server-side encryption with a customer-provided encryption key was + // requested, the response will include this header to provide round-trip message + // integrity verification of the customer-provided encryption key. SSECustomerKeyMD5 *string - // If present, specifies the ID of the Amazon Web Services Key Management Service - // (Amazon Web Services KMS) symmetric customer managed key that was used for the - // object. + // If present, specifies the ID of the Key Management Service (KMS) symmetric + // encryption customer managed key that was used for the object. SSEKMSKeyId *string // The server-side encryption algorithm used when storing this object in Amazon S3 - // (for example, AES256, aws:kms). + // (for example, AES256 , aws:kms ). ServerSideEncryption types.ServerSideEncryption // Metadata pertaining to the operation's result. @@ -332,6 +293,9 @@ func (c *Client) addOperationUploadPartCopyMiddlewares(stack *middleware.Stack, if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -359,7 +323,7 @@ func (c *Client) addOperationUploadPartCopyMiddlewares(stack *middleware.Stack, if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -371,6 +335,9 @@ func (c *Client) addOperationUploadPartCopyMiddlewares(stack *middleware.Stack, if err = swapWithCustomHTTPSignerMiddleware(stack, options); err != nil { return err } + if err = addUploadPartCopyResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpUploadPartCopyValidationMiddleware(stack); err != nil { return err } @@ -380,6 +347,9 @@ func (c *Client) addOperationUploadPartCopyMiddlewares(stack *middleware.Stack, if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addUploadPartCopyUpdateEndpoint(stack, options); err != nil { return err } @@ -398,9 +368,22 @@ func (c *Client) addOperationUploadPartCopyMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } +func (v *UploadPartCopyInput) bucket() (string, bool) { + if v.Bucket == nil { + return "", false + } + return *v.Bucket, true +} + func newServiceMetadataMiddleware_opUploadPartCopy(region string) *awsmiddleware.RegisterServiceMetadata { return &awsmiddleware.RegisterServiceMetadata{ Region: region, @@ -435,3 +418,139 @@ func addUploadPartCopyUpdateEndpoint(stack *middleware.Stack, options Options) e DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opUploadPartCopyResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opUploadPartCopyResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opUploadPartCopyResolveEndpointMiddleware) 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) + } + + input, ok := in.Parameters.(*UploadPartCopyInput) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.Bucket = input.Bucket + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addUploadPartCopyResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opUploadPartCopyResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_WriteGetObjectResponse.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_WriteGetObjectResponse.go index 78eeadd45..751f646dc 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_WriteGetObjectResponse.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/api_op_WriteGetObjectResponse.go @@ -4,13 +4,19 @@ package s3 import ( "context" + "errors" "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + "github.com/aws/aws-sdk-go-v2/internal/v4a" s3cust "github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations" "github.com/aws/aws-sdk-go-v2/service/s3/types" smithy "github.com/aws/smithy-go" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" smithyhttp "github.com/aws/smithy-go/transport/http" "io" "strings" @@ -19,20 +25,18 @@ import ( // Passes transformed objects to a GetObject operation when using Object Lambda // access points. For information about Object Lambda access points, see -// Transforming objects with Object Lambda access points -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/transforming-objects.html) +// Transforming objects with Object Lambda access points (https://docs.aws.amazon.com/AmazonS3/latest/userguide/transforming-objects.html) // in the Amazon S3 User Guide. This operation supports metadata that can be -// returned by GetObject -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html), in -// addition to RequestRoute, RequestToken, StatusCode, ErrorCode, and ErrorMessage. -// The GetObject response metadata is supported so that the WriteGetObjectResponse -// caller, typically an Lambda function, can provide the same metadata when it -// internally invokes GetObject. When WriteGetObjectResponse is called by a -// customer-owned Lambda function, the metadata returned to the end user GetObject -// call might differ from what Amazon S3 would normally return. You can include any -// number of metadata headers. When including a metadata header, it should be -// prefaced with x-amz-meta. For example, x-amz-meta-my-custom-header: -// MyCustomValue. The primary use case for this is to forward GetObject metadata. +// returned by GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) +// , in addition to RequestRoute , RequestToken , StatusCode , ErrorCode , and +// ErrorMessage . The GetObject response metadata is supported so that the +// WriteGetObjectResponse caller, typically an Lambda function, can provide the +// same metadata when it internally invokes GetObject . When WriteGetObjectResponse +// is called by a customer-owned Lambda function, the metadata returned to the end +// user GetObject call might differ from what Amazon S3 would normally return. You +// can include any number of metadata headers. When including a metadata header, it +// should be prefaced with x-amz-meta . For example, x-amz-meta-my-custom-header: +// MyCustomValue . The primary use case for this is to forward GetObject metadata. // Amazon Web Services provides some prebuilt Lambda functions that you can use // with S3 Object Lambda to detect and redact personally identifiable information // (PII) and decompress S3 objects. These Lambda functions are available in the @@ -52,9 +56,8 @@ import ( // equipped to decompress objects stored in S3 in one of six compressed file // formats including bzip2, gzip, snappy, zlib, zstandard and ZIP. For information // on how to view and use these functions, see Using Amazon Web Services built -// Lambda functions -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/olap-examples.html) in -// the Amazon S3 User Guide. +// Lambda functions (https://docs.aws.amazon.com/AmazonS3/latest/userguide/olap-examples.html) +// in the Amazon S3 User Guide. func (c *Client) WriteGetObjectResponse(ctx context.Context, params *WriteGetObjectResponseInput, optFns ...func(*Options)) (*WriteGetObjectResponseOutput, error) { if params == nil { params = &WriteGetObjectResponseInput{} @@ -102,8 +105,7 @@ type WriteGetObjectResponseInput struct { // Lambda function. This may not match the checksum for the object stored in Amazon // S3. Amazon S3 will perform validation of the checksum values only when the // original GetObject request required checksum validation. For more information - // about checksums, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // about checksums, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. Only one checksum header can be specified at a // time. If you supply multiple checksum headers, this request will fail. ChecksumCRC32 *string @@ -114,8 +116,7 @@ type WriteGetObjectResponseInput struct { // Lambda function. This may not match the checksum for the object stored in Amazon // S3. Amazon S3 will perform validation of the checksum values only when the // original GetObject request required checksum validation. For more information - // about checksums, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // about checksums, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. Only one checksum header can be specified at a // time. If you supply multiple checksum headers, this request will fail. ChecksumCRC32C *string @@ -126,8 +127,7 @@ type WriteGetObjectResponseInput struct { // function. This may not match the checksum for the object stored in Amazon S3. // Amazon S3 will perform validation of the checksum values only when the original // GetObject request required checksum validation. For more information about - // checksums, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // checksums, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. Only one checksum header can be specified at a // time. If you supply multiple checksum headers, this request will fail. ChecksumSHA1 *string @@ -138,8 +138,7 @@ type WriteGetObjectResponseInput struct { // Lambda function. This may not match the checksum for the object stored in Amazon // S3. Amazon S3 will perform validation of the checksum values only when the // original GetObject request required checksum validation. For more information - // about checksums, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // about checksums, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. Only one checksum header can be specified at a // time. If you supply multiple checksum headers, this request will fail. ChecksumSHA256 *string @@ -164,8 +163,8 @@ type WriteGetObjectResponseInput struct { // A standard MIME type describing the format of the object data. ContentType *string - // Specifies whether an object stored in Amazon S3 is (true) or is not (false) a - // delete marker. + // Specifies whether an object stored in Amazon S3 is ( true ) or is not ( false ) + // a delete marker. DeleteMarker bool // An opaque identifier assigned by a web server to a specific version of a @@ -173,15 +172,16 @@ type WriteGetObjectResponseInput struct { ETag *string // A string that uniquely identifies an error condition. Returned in the tag of - // the error XML response for a corresponding GetObject call. Cannot be used with a - // successful StatusCode header or when the transformed object is provided in the - // body. All error codes from S3 are sentence-cased. The regular expression (regex) - // value is "^[A-Z][a-zA-Z]+$". + // the error XML response for a corresponding GetObject call. Cannot be used with + // a successful StatusCode header or when the transformed object is provided in + // the body. All error codes from S3 are sentence-cased. The regular expression + // (regex) value is "^[A-Z][a-zA-Z]+$" . ErrorCode *string // Contains a generic description of the error condition. Returned in the tag of - // the error XML response for a corresponding GetObject call. Cannot be used with a - // successful StatusCode header or when the transformed object is provided in body. + // the error XML response for a corresponding GetObject call. Cannot be used with + // a successful StatusCode header or when the transformed object is provided in + // body. ErrorMessage *string // If the object expiration is configured (see PUT Bucket lifecycle), the response @@ -209,8 +209,8 @@ type WriteGetObjectResponseInput struct { ObjectLockLegalHoldStatus types.ObjectLockLegalHoldStatus // Indicates whether an object stored in Amazon S3 has Object Lock enabled. For - // more information about S3 Object Lock, see Object Lock - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html). + // more information about S3 Object Lock, see Object Lock (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html) + // . ObjectLockMode types.ObjectLockMode // The date and time when Object Lock is configured to expire. @@ -219,9 +219,9 @@ type WriteGetObjectResponseInput struct { // The count of parts this object has. PartsCount int32 - // Indicates if request involves bucket that is either a source or destination in a - // Replication rule. For more information about S3 Replication, see Replication - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/replication.html). + // Indicates if request involves bucket that is either a source or destination in + // a Replication rule. For more information about S3 Replication, see Replication (https://docs.aws.amazon.com/AmazonS3/latest/userguide/replication.html) + // . ReplicationStatus types.ReplicationStatus // If present, indicates that the requester was successfully charged for the @@ -238,59 +238,41 @@ type WriteGetObjectResponseInput struct { // 128-bit MD5 digest of customer-provided encryption key used in Amazon S3 to // encrypt data stored in S3. For more information, see Protecting data using - // server-side encryption with customer-provided encryption keys (SSE-C) - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html). + // server-side encryption with customer-provided encryption keys (SSE-C) (https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html) + // . SSECustomerKeyMD5 *string - // If present, specifies the ID of the Amazon Web Services Key Management Service - // (Amazon Web Services KMS) symmetric customer managed key that was used for - // stored in Amazon S3 object. + // If present, specifies the ID (Key ID, Key ARN, or Key Alias) of the Amazon Web + // Services Key Management Service (Amazon Web Services KMS) symmetric encryption + // customer managed key that was used for stored in Amazon S3 object. SSEKMSKeyId *string // The server-side encryption algorithm used when storing requested object in - // Amazon S3 (for example, AES256, aws:kms). + // Amazon S3 (for example, AES256, aws:kms ). ServerSideEncryption types.ServerSideEncryption // The integer status code for an HTTP response of a corresponding GetObject - // request. Status Codes - // - // * 200 - OK - // - // * 206 - Partial Content - // - // * 304 - Not - // Modified - // - // * 400 - Bad Request - // - // * 401 - Unauthorized - // - // * 403 - Forbidden - // - // * 404 - - // Not Found - // - // * 405 - Method Not Allowed - // - // * 409 - Conflict - // - // * 411 - Length - // Required - // - // * 412 - Precondition Failed - // - // * 416 - Range Not Satisfiable - // - // * 500 - - // Internal Server Error - // - // * 503 - Service Unavailable + // request. The following is a list of status codes. + // - 200 - OK + // - 206 - Partial Content + // - 304 - Not Modified + // - 400 - Bad Request + // - 401 - Unauthorized + // - 403 - Forbidden + // - 404 - Not Found + // - 405 - Method Not Allowed + // - 409 - Conflict + // - 411 - Length Required + // - 412 - Precondition Failed + // - 416 - Range Not Satisfiable + // - 500 - Internal Server Error + // - 503 - Service Unavailable StatusCode int32 // Provides storage class information of the object. Amazon S3 returns this header // for all objects except for S3 Standard storage class objects. For more - // information, see Storage Classes - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html). + // information, see Storage Classes (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html) + // . StorageClass types.StorageClass // The number of tags, if any, on the object. @@ -318,6 +300,9 @@ func (c *Client) addOperationWriteGetObjectResponseMiddlewares(stack *middleware if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -348,7 +333,7 @@ func (c *Client) addOperationWriteGetObjectResponseMiddlewares(stack *middleware if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -363,6 +348,9 @@ func (c *Client) addOperationWriteGetObjectResponseMiddlewares(stack *middleware if err = addEndpointPrefix_opWriteGetObjectResponseMiddleware(stack); err != nil { return err } + if err = addWriteGetObjectResponseResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpWriteGetObjectResponseValidationMiddleware(stack); err != nil { return err } @@ -372,6 +360,9 @@ func (c *Client) addOperationWriteGetObjectResponseMiddlewares(stack *middleware if err = addMetadataRetrieverMiddleware(stack); err != nil { return err } + if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + return err + } if err = addWriteGetObjectResponseUpdateEndpoint(stack, options); err != nil { return err } @@ -387,6 +378,12 @@ func (c *Client) addOperationWriteGetObjectResponseMiddlewares(stack *middleware if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addSerializeImmutableHostnameBucketMiddleware(stack, options); err != nil { + return err + } return nil } @@ -455,3 +452,134 @@ func addWriteGetObjectResponseUpdateEndpoint(stack *middleware.Stack, options Op DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, }) } + +type opWriteGetObjectResponseResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opWriteGetObjectResponseResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opWriteGetObjectResponseResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + params.UseObjectLambdaEndpoint = ptr.Bool(true) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "s3" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, internalauth.SigV4) + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "s3" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + ctx = s3cust.SetSignerVersion(ctx, v4Scheme.Name) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("s3") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + ctx = s3cust.SetSignerVersion(ctx, v4a.Version) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addWriteGetObjectResponseResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opWriteGetObjectResponseResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + Endpoint: options.BaseEndpoint, + ForcePathStyle: options.UsePathStyle, + Accelerate: options.UseAccelerate, + DisableMultiRegionAccessPoints: options.DisableMultiRegionAccessPoints, + UseArnRegion: options.UseARNRegion, + }, + }, "ResolveEndpoint", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/bucketer.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/bucketer.go new file mode 100644 index 000000000..4e7f7e24e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/bucketer.go @@ -0,0 +1,15 @@ +package s3 + +// implemented by all S3 input structures +type bucketer interface { + bucket() (string, bool) +} + +func bucketFromInput(params interface{}) (string, bool) { + v, ok := params.(bucketer) + if !ok { + return "", false + } + + return v.bucket() +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/deserializers.go index 995d909cf..fc192a326 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/deserializers.go @@ -2369,6 +2369,11 @@ func (m *awsRestxml_deserializeOpGetBucketAccelerateConfiguration) HandleDeseria output := &GetBucketAccelerateConfigurationOutput{} out.Result = output + err = awsRestxml_deserializeOpHttpBindingsGetBucketAccelerateConfigurationOutput(output, response) + if err != nil { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("failed to decode response with invalid Http bindings, %w", err)} + } + var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) body := io.TeeReader(response.Body, ringBuffer) @@ -2440,6 +2445,18 @@ func awsRestxml_deserializeOpErrorGetBucketAccelerateConfiguration(response *smi } } +func awsRestxml_deserializeOpHttpBindingsGetBucketAccelerateConfigurationOutput(v *GetBucketAccelerateConfigurationOutput, response *smithyhttp.Response) error { + if v == nil { + return fmt.Errorf("unsupported deserialization for nil %T", v) + } + + if headerValues := response.Header.Values("x-amz-request-charged"); len(headerValues) != 0 { + headerValues[0] = strings.TrimSpace(headerValues[0]) + v.RequestCharged = types.RequestCharged(headerValues[0]) + } + + return nil +} func awsRestxml_deserializeOpDocumentGetBucketAccelerateConfigurationOutput(v **GetBucketAccelerateConfigurationOutput, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -6827,6 +6844,9 @@ func awsRestxml_deserializeOpErrorHeadObject(response *smithyhttp.Response, meta } errorBody.Seek(0, io.SeekStart) switch { + case strings.EqualFold("NotFound", errorCode): + return awsRestxml_deserializeErrorNotFound(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -7947,6 +7967,11 @@ func (m *awsRestxml_deserializeOpListMultipartUploads) HandleDeserialize(ctx con output := &ListMultipartUploadsOutput{} out.Result = output + err = awsRestxml_deserializeOpHttpBindingsListMultipartUploadsOutput(output, response) + if err != nil { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("failed to decode response with invalid Http bindings, %w", err)} + } + var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) body := io.TeeReader(response.Body, ringBuffer) @@ -8018,6 +8043,18 @@ func awsRestxml_deserializeOpErrorListMultipartUploads(response *smithyhttp.Resp } } +func awsRestxml_deserializeOpHttpBindingsListMultipartUploadsOutput(v *ListMultipartUploadsOutput, response *smithyhttp.Response) error { + if v == nil { + return fmt.Errorf("unsupported deserialization for nil %T", v) + } + + if headerValues := response.Header.Values("x-amz-request-charged"); len(headerValues) != 0 { + headerValues[0] = strings.TrimSpace(headerValues[0]) + v.RequestCharged = types.RequestCharged(headerValues[0]) + } + + return nil +} func awsRestxml_deserializeOpDocumentListMultipartUploadsOutput(v **ListMultipartUploadsOutput, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -8229,6 +8266,11 @@ func (m *awsRestxml_deserializeOpListObjects) HandleDeserialize(ctx context.Cont output := &ListObjectsOutput{} out.Result = output + err = awsRestxml_deserializeOpHttpBindingsListObjectsOutput(output, response) + if err != nil { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("failed to decode response with invalid Http bindings, %w", err)} + } + var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) body := io.TeeReader(response.Body, ringBuffer) @@ -8303,6 +8345,18 @@ func awsRestxml_deserializeOpErrorListObjects(response *smithyhttp.Response, met } } +func awsRestxml_deserializeOpHttpBindingsListObjectsOutput(v *ListObjectsOutput, response *smithyhttp.Response) error { + if v == nil { + return fmt.Errorf("unsupported deserialization for nil %T", v) + } + + if headerValues := response.Header.Values("x-amz-request-charged"); len(headerValues) != 0 { + headerValues[0] = strings.TrimSpace(headerValues[0]) + v.RequestCharged = types.RequestCharged(headerValues[0]) + } + + return nil +} func awsRestxml_deserializeOpDocumentListObjectsOutput(v **ListObjectsOutput, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -8488,6 +8542,11 @@ func (m *awsRestxml_deserializeOpListObjectsV2) HandleDeserialize(ctx context.Co output := &ListObjectsV2Output{} out.Result = output + err = awsRestxml_deserializeOpHttpBindingsListObjectsV2Output(output, response) + if err != nil { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("failed to decode response with invalid Http bindings, %w", err)} + } + var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) body := io.TeeReader(response.Body, ringBuffer) @@ -8562,6 +8621,18 @@ func awsRestxml_deserializeOpErrorListObjectsV2(response *smithyhttp.Response, m } } +func awsRestxml_deserializeOpHttpBindingsListObjectsV2Output(v *ListObjectsV2Output, response *smithyhttp.Response) error { + if v == nil { + return fmt.Errorf("unsupported deserialization for nil %T", v) + } + + if headerValues := response.Header.Values("x-amz-request-charged"); len(headerValues) != 0 { + headerValues[0] = strings.TrimSpace(headerValues[0]) + v.RequestCharged = types.RequestCharged(headerValues[0]) + } + + return nil +} func awsRestxml_deserializeOpDocumentListObjectsV2Output(v **ListObjectsV2Output, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -8777,6 +8848,11 @@ func (m *awsRestxml_deserializeOpListObjectVersions) HandleDeserialize(ctx conte output := &ListObjectVersionsOutput{} out.Result = output + err = awsRestxml_deserializeOpHttpBindingsListObjectVersionsOutput(output, response) + if err != nil { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("failed to decode response with invalid Http bindings, %w", err)} + } + var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) body := io.TeeReader(response.Body, ringBuffer) @@ -8848,6 +8924,18 @@ func awsRestxml_deserializeOpErrorListObjectVersions(response *smithyhttp.Respon } } +func awsRestxml_deserializeOpHttpBindingsListObjectVersionsOutput(v *ListObjectVersionsOutput, response *smithyhttp.Response) error { + if v == nil { + return fmt.Errorf("unsupported deserialization for nil %T", v) + } + + if headerValues := response.Header.Values("x-amz-request-charged"); len(headerValues) != 0 { + headerValues[0] = strings.TrimSpace(headerValues[0]) + v.RequestCharged = types.RequestCharged(headerValues[0]) + } + + return nil +} func awsRestxml_deserializeOpDocumentListObjectVersionsOutput(v **ListObjectVersionsOutput, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -18361,6 +18449,12 @@ func awsRestxml_deserializeDocumentObject(v **types.Object, decoder smithyxml.No return err } + case strings.EqualFold("RestoreStatus", t.Name.Local): + nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) + if err := awsRestxml_deserializeDocumentRestoreStatus(&sv.RestoreStatus, nodeDecoder); err != nil { + return err + } + case strings.EqualFold("Size", t.Name.Local): val, err := decoder.Value() if err != nil { @@ -18972,6 +19066,12 @@ func awsRestxml_deserializeDocumentObjectVersion(v **types.ObjectVersion, decode return err } + case strings.EqualFold("RestoreStatus", t.Name.Local): + nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) + if err := awsRestxml_deserializeDocumentRestoreStatus(&sv.RestoreStatus, nodeDecoder); err != nil { + return err + } + case strings.EqualFold("Size", t.Name.Local): val, err := decoder.Value() if err != nil { @@ -20591,6 +20691,75 @@ func awsRestxml_deserializeDocumentReplicationTimeValue(v **types.ReplicationTim return nil } +func awsRestxml_deserializeDocumentRestoreStatus(v **types.RestoreStatus, decoder smithyxml.NodeDecoder) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + var sv *types.RestoreStatus + if *v == nil { + sv = &types.RestoreStatus{} + } 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("IsRestoreInProgress", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv, err := strconv.ParseBool(string(val)) + if err != nil { + return fmt.Errorf("expected IsRestoreInProgress to be of type *bool, got %T instead", val) + } + sv.IsRestoreInProgress = xtv + } + + case strings.EqualFold("RestoreExpiryDate", 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.RestoreExpiryDate = ptr.Time(t) + } + + 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 awsRestxml_deserializeDocumentRoutingRule(v **types.RoutingRule, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/endpoints.go index 8df6368cd..c6012bdb2 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/endpoints.go @@ -8,9 +8,15 @@ import ( "fmt" "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/endpoints/awsrulesfn" internalendpoints "github.com/aws/aws-sdk-go-v2/service/s3/internal/endpoints" + smithy "github.com/aws/smithy-go" + 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" smithyhttp "github.com/aws/smithy-go/transport/http" + "net/http" "net/url" "strings" ) @@ -39,13 +45,6 @@ func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointRe return fn(region, options) } -func resolveDefaultEndpointConfiguration(o *Options) { - if o.EndpointResolver != nil { - return - } - o.EndpointResolver = NewDefaultEndpointResolver() -} - // 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 @@ -79,6 +78,10 @@ func (*ResolveEndpoint) ID() string { 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) @@ -94,6 +97,11 @@ func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.Ser 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) } @@ -129,27 +137,10 @@ func removeResolveEndpointMiddleware(stack *middleware.Stack) error { type wrappedEndpointResolver struct { awsResolver aws.EndpointResolverWithOptions - resolver EndpointResolver } func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - if w.awsResolver == nil { - goto fallback - } - endpoint, err = w.awsResolver.ResolveEndpoint(ServiceID, region, options) - if err == nil { - return endpoint, nil - } - - if nf := (&aws.EndpointNotFoundError{}); !errors.As(err, &nf) { - return endpoint, err - } - -fallback: - if w.resolver == nil { - return endpoint, fmt.Errorf("default endpoint resolver provided was nil") - } - return w.resolver.ResolveEndpoint(region, options) + return w.awsResolver.ResolveEndpoint(ServiceID, region, options) } type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error) @@ -160,12 +151,13 @@ func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, opti var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil) -// withEndpointResolver returns an EndpointResolver that first delegates endpoint resolution to the awsResolver. -// If awsResolver returns aws.EndpointNotFoundError error, the resolver will use the the provided -// fallbackResolver for resolution. +// 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. // -// fallbackResolver must not be nil -func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions, fallbackResolver EndpointResolver) EndpointResolver { +// 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 { @@ -176,7 +168,6 @@ func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptio return &wrappedEndpointResolver{ awsResolver: resolver, - resolver: fallbackResolver, } } @@ -206,3 +197,4131 @@ func finalizeClientEndpointResolverOptions(options *Options) { } } + +func resolveEndpointResolverV2(options *Options) { + if options.EndpointResolverV2 == nil { + options.EndpointResolverV2 = NewDefaultEndpointResolverV2() + } +} + +// Utility function to aid with translating pseudo-regions to classical regions +// with the appropriate setting indicated by the pseudo-region +func mapPseudoRegion(pr string) (region string, fips aws.FIPSEndpointState) { + const fipsInfix = "-fips-" + const fipsPrefix = "fips-" + const fipsSuffix = "-fips" + + if strings.Contains(pr, fipsInfix) || + strings.Contains(pr, fipsPrefix) || + strings.Contains(pr, fipsSuffix) { + region = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll( + pr, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "") + fips = aws.FIPSEndpointStateEnabled + } else { + region = pr + } + + return region, fips +} + +// builtInParameterResolver is the interface responsible for resolving BuiltIn +// values during the sourcing of EndpointParameters +type builtInParameterResolver interface { + ResolveBuiltIns(*EndpointParameters) error +} + +// builtInResolver resolves modeled BuiltIn values using only the members defined +// below. +type builtInResolver struct { + // The AWS region used to dispatch the request. + Region string + + // Sourced BuiltIn value in a historical enabled or disabled state. + UseFIPS aws.FIPSEndpointState + + // Sourced BuiltIn value in a historical enabled or disabled state. + UseDualStack aws.DualStackEndpointState + + // Base endpoint that can potentially be modified during Endpoint resolution. + Endpoint *string + + // When true, force a path-style endpoint to be used where the bucket name is part + // of the path. + ForcePathStyle bool + + // When true, use S3 Accelerate. NOTE: Not all regions support S3 accelerate. + Accelerate bool + + // Whether the global endpoint should be used, rather then the regional endpoint + // for us-east-1. + UseGlobalEndpoint bool + + // Whether multi-region access points (MRAP) should be disabled. + DisableMultiRegionAccessPoints bool + + // When an Access Point ARN is provided and this flag is enabled, the SDK MUST use + // the ARN's region when constructing the endpoint instead of the client's + // configured region. + UseArnRegion bool +} + +// Invoked at runtime to resolve BuiltIn Values. Only resolution code specific to +// each BuiltIn value is generated. +func (b *builtInResolver) ResolveBuiltIns(params *EndpointParameters) error { + + region, _ := mapPseudoRegion(b.Region) + if len(region) == 0 { + return fmt.Errorf("Could not resolve AWS::Region") + } else { + params.Region = aws.String(region) + } + if b.UseFIPS == aws.FIPSEndpointStateEnabled { + params.UseFIPS = aws.Bool(true) + } else { + params.UseFIPS = aws.Bool(false) + } + if b.UseDualStack == aws.DualStackEndpointStateEnabled { + params.UseDualStack = aws.Bool(true) + } else { + params.UseDualStack = aws.Bool(false) + } + params.Endpoint = b.Endpoint + params.ForcePathStyle = aws.Bool(b.ForcePathStyle) + params.Accelerate = aws.Bool(b.Accelerate) + params.UseGlobalEndpoint = aws.Bool(b.UseGlobalEndpoint) + params.DisableMultiRegionAccessPoints = aws.Bool(b.DisableMultiRegionAccessPoints) + params.UseArnRegion = aws.Bool(b.UseArnRegion) + return nil +} + +// EndpointParameters provides the parameters that influence how endpoints are +// resolved. +type EndpointParameters struct { + // The S3 bucket used to send the request. This is an optional parameter that will + // be set automatically for operations that are scoped to an S3 bucket. + // + // Parameter + // is required. + Bucket *string + + // The AWS region used to dispatch the request. + // + // Parameter is + // required. + // + // AWS::Region + Region *string + + // 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 + + // 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 + + // Override the endpoint used to send this request + // + // Parameter is + // required. + // + // SDK::Endpoint + Endpoint *string + + // When true, force a path-style endpoint to be used where the bucket name is part + // of the path. + // + // Defaults to false if no value is + // provided. + // + // AWS::S3::ForcePathStyle + ForcePathStyle *bool + + // When true, use S3 Accelerate. NOTE: Not all regions support S3 + // accelerate. + // + // Defaults to false if no value is provided. + // + // AWS::S3::Accelerate + Accelerate *bool + + // 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::S3::UseGlobalEndpoint + UseGlobalEndpoint *bool + + // Internal parameter to use object lambda endpoint for an operation (eg: + // WriteGetObjectResponse) + // + // Parameter is required. + UseObjectLambdaEndpoint *bool + + // Internal parameter to disable Access Point Buckets + // + // Parameter is required. + DisableAccessPoints *bool + + // Whether multi-region access points (MRAP) should be disabled. + // + // Defaults to false + // if no value is provided. + // + // AWS::S3::DisableMultiRegionAccessPoints + DisableMultiRegionAccessPoints *bool + + // When an Access Point ARN is provided and this flag is enabled, the SDK MUST use + // the ARN's region when constructing the endpoint instead of the client's + // configured region. + // + // Parameter is required. + // + // AWS::S3::UseArnRegion + UseArnRegion *bool +} + +// ValidateRequired validates required parameters are set. +func (p EndpointParameters) ValidateRequired() error { + if p.Accelerate == nil { + return fmt.Errorf("parameter Accelerate is required") + } + + if p.DisableMultiRegionAccessPoints == nil { + return fmt.Errorf("parameter DisableMultiRegionAccessPoints is required") + } + + if p.ForcePathStyle == nil { + return fmt.Errorf("parameter ForcePathStyle is required") + } + + 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.Accelerate == nil { + p.Accelerate = ptr.Bool(false) + } + + if p.DisableMultiRegionAccessPoints == nil { + p.DisableMultiRegionAccessPoints = ptr.Bool(false) + } + + if p.ForcePathStyle == nil { + p.ForcePathStyle = ptr.Bool(false) + } + + 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 +} + +// 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) + } + _UseFIPS := *params.UseFIPS + _UseDualStack := *params.UseDualStack + _ForcePathStyle := *params.ForcePathStyle + _Accelerate := *params.Accelerate + _UseGlobalEndpoint := *params.UseGlobalEndpoint + _DisableMultiRegionAccessPoints := *params.DisableMultiRegionAccessPoints + + if exprVal := params.Region; exprVal != nil { + _Region := *exprVal + _ = _Region + if _Accelerate == true { + if _UseFIPS == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Accelerate cannot be used with FIPS") + } + } + if _UseDualStack == true { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + return endpoint, fmt.Errorf("endpoint rule error, %s", "Cannot set dual-stack in combination with a custom endpoint.") + } + } + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if _UseFIPS == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "A custom endpoint cannot be combined with FIPS") + } + } + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if _Accelerate == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "A custom endpoint cannot be combined with S3 Accelerate") + } + } + if _UseFIPS == true { + if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { + _partitionResult := *exprVal + _ = _partitionResult + if _partitionResult.Name == "aws-cn" { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Partition does not support FIPS") + } + } + } + if exprVal := params.Bucket; exprVal != nil { + _Bucket := *exprVal + _ = _Bucket + if exprVal := rulesfn.SubString(_Bucket, 49, 50, true); exprVal != nil { + _hardwareType := *exprVal + _ = _hardwareType + if exprVal := rulesfn.SubString(_Bucket, 8, 12, true); exprVal != nil { + _regionPrefix := *exprVal + _ = _regionPrefix + if exprVal := rulesfn.SubString(_Bucket, 0, 7, true); exprVal != nil { + _bucketAliasSuffix := *exprVal + _ = _bucketAliasSuffix + if exprVal := rulesfn.SubString(_Bucket, 32, 49, true); exprVal != nil { + _outpostId := *exprVal + _ = _outpostId + if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { + _regionPartition := *exprVal + _ = _regionPartition + if _bucketAliasSuffix == "--op-s3" { + if rulesfn.IsValidHostLabel(_outpostId, false) { + if _hardwareType == "e" { + if _regionPrefix == "beta" { + if !(params.Endpoint != nil) { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Expected a endpoint to be specified but no endpoint was found") + } + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".ec2.") + out.WriteString(_url.Authority) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3-outposts", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".ec2.s3-outposts.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_regionPartition.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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3-outposts", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + if _hardwareType == "o" { + if _regionPrefix == "beta" { + if !(params.Endpoint != nil) { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Expected a endpoint to be specified but no endpoint was found") + } + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".op-") + out.WriteString(_outpostId) + out.WriteString(".") + out.WriteString(_url.Authority) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3-outposts", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".op-") + out.WriteString(_outpostId) + out.WriteString(".s3-outposts.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_regionPartition.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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3-outposts", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Unrecognized hardware type: \"Expected hardware type o or e but got ") + out.WriteString(_hardwareType) + out.WriteString("\"") + return out.String() + }()) + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid ARN: The outpost Id must only contain a-z, A-Z, 0-9 and `-`.") + } + } + } + } + } + } + } + if exprVal := params.Bucket; exprVal != nil { + _Bucket := *exprVal + _ = _Bucket + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if !(rulesfn.ParseURL(_Endpoint) != nil) { + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Custom endpoint `") + out.WriteString(_Endpoint) + out.WriteString("` was not a valid URI") + return out.String() + }()) + } + } + if _ForcePathStyle == false { + if awsrulesfn.IsVirtualHostableS3Bucket(_Bucket, false) { + if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { + _partitionResult := *exprVal + _ = _partitionResult + if rulesfn.IsValidHostLabel(_Region, false) { + if _Accelerate == true { + if _partitionResult.Name == "aws-cn" { + return endpoint, fmt.Errorf("endpoint rule error, %s", "S3 Accelerate cannot be used in this region") + } + } + if _UseDualStack == true { + if _UseFIPS == true { + if _Accelerate == false { + if !(params.Endpoint != nil) { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3-fips.dualstack.us-east-1.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseDualStack == true { + if _UseFIPS == true { + if _Accelerate == false { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3-fips.dualstack.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseDualStack == true { + if _UseFIPS == true { + if _Accelerate == false { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3-fips.dualstack.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == true { + if _Accelerate == false { + if !(params.Endpoint != nil) { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3-fips.us-east-1.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == true { + if _Accelerate == false { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3-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{}, + Properties: func() smithy.Properties { + var out smithy.Properties + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == true { + if _Accelerate == false { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3-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{}, + Properties: func() smithy.Properties { + var out smithy.Properties + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseDualStack == true { + if _UseFIPS == false { + if _Accelerate == true { + if !(params.Endpoint != nil) { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3-accelerate.dualstack.us-east-1.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseDualStack == true { + if _UseFIPS == false { + if _Accelerate == true { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3-accelerate.dualstack.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseDualStack == true { + if _UseFIPS == false { + if _Accelerate == true { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3-accelerate.dualstack.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseDualStack == true { + if _UseFIPS == false { + if _Accelerate == false { + if !(params.Endpoint != nil) { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3.dualstack.us-east-1.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseDualStack == true { + if _UseFIPS == false { + if _Accelerate == false { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3.dualstack.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseDualStack == true { + if _UseFIPS == false { + if _Accelerate == false { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3.dualstack.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == false { + if _Accelerate == false { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + if _url.IsIp == true { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_url.Authority) + out.WriteString(_url.NormalizedPath) + out.WriteString(_Bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == false { + if _Accelerate == false { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + if _url.IsIp == false { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_Bucket) + out.WriteString(".") + out.WriteString(_url.Authority) + out.WriteString(_url.Path) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == false { + if _Accelerate == false { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + if _url.IsIp == true { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + if _Region == "us-east-1" { + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_url.Authority) + out.WriteString(_url.NormalizedPath) + out.WriteString(_Bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_url.Authority) + out.WriteString(_url.NormalizedPath) + out.WriteString(_Bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == false { + if _Accelerate == false { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + if _url.IsIp == false { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + if _Region == "us-east-1" { + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_Bucket) + out.WriteString(".") + out.WriteString(_url.Authority) + out.WriteString(_url.Path) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_Bucket) + out.WriteString(".") + out.WriteString(_url.Authority) + out.WriteString(_url.Path) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == false { + if _Accelerate == false { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + if _url.IsIp == true { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_url.Authority) + out.WriteString(_url.NormalizedPath) + out.WriteString(_Bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == false { + if _Accelerate == false { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + if _url.IsIp == false { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_Bucket) + out.WriteString(".") + out.WriteString(_url.Authority) + out.WriteString(_url.Path) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == false { + if _Accelerate == true { + if !(params.Endpoint != nil) { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3-accelerate.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == false { + if _Accelerate == true { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + if _Region == "us-east-1" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3-accelerate.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3-accelerate.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == false { + if _Accelerate == true { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3-accelerate.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == false { + if _Accelerate == false { + if !(params.Endpoint != nil) { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == false { + if _Accelerate == false { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + if _Region == "us-east-1" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseDualStack == false { + if _UseFIPS == false { + if _Accelerate == false { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Bucket) + out.WriteString(".s3.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid region: region was not a valid DNS name.") + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + } + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + if _url.Scheme == "http" { + if awsrulesfn.IsVirtualHostableS3Bucket(_Bucket, true) { + if _ForcePathStyle == false { + if _UseFIPS == false { + if _UseDualStack == false { + if _Accelerate == false { + if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { + _partitionResult := *exprVal + _ = _partitionResult + if rulesfn.IsValidHostLabel(_Region, false) { + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_Bucket) + out.WriteString(".") + out.WriteString(_url.Authority) + out.WriteString(_url.Path) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid region: region was not a valid DNS name.") + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + } + } + } + } + } + } + } + if _ForcePathStyle == false { + if exprVal := awsrulesfn.ParseARN(_Bucket); exprVal != nil { + _bucketArn := *exprVal + _ = _bucketArn + if exprVal := _bucketArn.ResourceId.Get(0); exprVal != nil { + _arnType := *exprVal + _ = _arnType + if !(_arnType == "") { + if _bucketArn.Service == "s3-object-lambda" { + if _arnType == "accesspoint" { + if exprVal := _bucketArn.ResourceId.Get(1); exprVal != nil { + _accessPointName := *exprVal + _ = _accessPointName + if !(_accessPointName == "") { + if _UseDualStack == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "S3 Object Lambda does not support Dual-stack") + } + if _Accelerate == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "S3 Object Lambda does not support S3 Accelerate") + } + if !(_bucketArn.Region == "") { + if exprVal := params.DisableAccessPoints; exprVal != nil { + _DisableAccessPoints := *exprVal + _ = _DisableAccessPoints + if _DisableAccessPoints == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Access points are not supported for this operation") + } + } + if !(_bucketArn.ResourceId.Get(2) != nil) { + if exprVal := params.UseArnRegion; exprVal != nil { + _UseArnRegion := *exprVal + _ = _UseArnRegion + if _UseArnRegion == false { + if !(_bucketArn.Region == _Region) { + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid configuration: region from ARN `") + out.WriteString(_bucketArn.Region) + out.WriteString("` does not match client region `") + out.WriteString(_Region) + out.WriteString("` and UseArnRegion is `false`") + return out.String() + }()) + } + } + } + if exprVal := awsrulesfn.GetPartition(_bucketArn.Region); exprVal != nil { + _bucketPartition := *exprVal + _ = _bucketPartition + if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { + _partitionResult := *exprVal + _ = _partitionResult + if _bucketPartition.Name == _partitionResult.Name { + if rulesfn.IsValidHostLabel(_bucketArn.Region, true) { + if _bucketArn.AccountId == "" { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid ARN: Missing account id") + } + if rulesfn.IsValidHostLabel(_bucketArn.AccountId, false) { + if rulesfn.IsValidHostLabel(_accessPointName, false) { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_accessPointName) + out.WriteString("-") + out.WriteString(_bucketArn.AccountId) + out.WriteString(".") + out.WriteString(_url.Authority) + out.WriteString(_url.Path) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3-object-lambda", + "signingRegion": _bucketArn.Region, + }, + }) + return out + }(), + }, nil + } + } + if _UseFIPS == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_accessPointName) + out.WriteString("-") + out.WriteString(_bucketArn.AccountId) + out.WriteString(".s3-object-lambda-fips.") + out.WriteString(_bucketArn.Region) + out.WriteString(".") + out.WriteString(_bucketPartition.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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3-object-lambda", + "signingRegion": _bucketArn.Region, + }, + }) + return out + }(), + }, nil + } + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_accessPointName) + out.WriteString("-") + out.WriteString(_bucketArn.AccountId) + out.WriteString(".s3-object-lambda.") + out.WriteString(_bucketArn.Region) + out.WriteString(".") + out.WriteString(_bucketPartition.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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3-object-lambda", + "signingRegion": _bucketArn.Region, + }, + }) + return out + }(), + }, nil + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid ARN: The access point name may only contain a-z, A-Z, 0-9 and `-`. Found: `") + out.WriteString(_accessPointName) + out.WriteString("`") + return out.String() + }()) + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid ARN: The account id may only contain a-z, A-Z, 0-9 and `-`. Found: `") + out.WriteString(_bucketArn.AccountId) + out.WriteString("`") + return out.String() + }()) + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid region in ARN: `") + out.WriteString(_bucketArn.Region) + out.WriteString("` (invalid DNS name)") + return out.String() + }()) + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Client was configured for partition `") + out.WriteString(_partitionResult.Name) + out.WriteString("` but ARN (`") + out.WriteString(_Bucket) + out.WriteString("`) has `") + out.WriteString(_bucketPartition.Name) + out.WriteString("`") + return out.String() + }()) + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid ARN: The ARN may only contain a single resource component after `accesspoint`.") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid ARN: bucket ARN is missing a region") + } + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid ARN: Expected a resource of the format `accesspoint:` but no name was provided") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid ARN: Object Lambda ARNs only support `accesspoint` arn types, but found: `") + out.WriteString(_arnType) + out.WriteString("`") + return out.String() + }()) + } + if _arnType == "accesspoint" { + if exprVal := _bucketArn.ResourceId.Get(1); exprVal != nil { + _accessPointName := *exprVal + _ = _accessPointName + if !(_accessPointName == "") { + if !(_bucketArn.Region == "") { + if _arnType == "accesspoint" { + if !(_bucketArn.Region == "") { + if exprVal := params.DisableAccessPoints; exprVal != nil { + _DisableAccessPoints := *exprVal + _ = _DisableAccessPoints + if _DisableAccessPoints == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Access points are not supported for this operation") + } + } + if !(_bucketArn.ResourceId.Get(2) != nil) { + if exprVal := params.UseArnRegion; exprVal != nil { + _UseArnRegion := *exprVal + _ = _UseArnRegion + if _UseArnRegion == false { + if !(_bucketArn.Region == _Region) { + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid configuration: region from ARN `") + out.WriteString(_bucketArn.Region) + out.WriteString("` does not match client region `") + out.WriteString(_Region) + out.WriteString("` and UseArnRegion is `false`") + return out.String() + }()) + } + } + } + if exprVal := awsrulesfn.GetPartition(_bucketArn.Region); exprVal != nil { + _bucketPartition := *exprVal + _ = _bucketPartition + if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { + _partitionResult := *exprVal + _ = _partitionResult + if _bucketPartition.Name == _partitionResult.Name { + if rulesfn.IsValidHostLabel(_bucketArn.Region, true) { + if _bucketArn.Service == "s3" { + if rulesfn.IsValidHostLabel(_bucketArn.AccountId, false) { + if rulesfn.IsValidHostLabel(_accessPointName, false) { + if _Accelerate == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Access Points do not support S3 Accelerate") + } + if _UseFIPS == true { + if _UseDualStack == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_accessPointName) + out.WriteString("-") + out.WriteString(_bucketArn.AccountId) + out.WriteString(".s3-accesspoint-fips.dualstack.") + out.WriteString(_bucketArn.Region) + out.WriteString(".") + out.WriteString(_bucketPartition.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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _bucketArn.Region, + }, + }) + return out + }(), + }, nil + } + } + if _UseFIPS == true { + if _UseDualStack == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_accessPointName) + out.WriteString("-") + out.WriteString(_bucketArn.AccountId) + out.WriteString(".s3-accesspoint-fips.") + out.WriteString(_bucketArn.Region) + out.WriteString(".") + out.WriteString(_bucketPartition.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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _bucketArn.Region, + }, + }) + return out + }(), + }, nil + } + } + if _UseFIPS == false { + if _UseDualStack == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_accessPointName) + out.WriteString("-") + out.WriteString(_bucketArn.AccountId) + out.WriteString(".s3-accesspoint.dualstack.") + out.WriteString(_bucketArn.Region) + out.WriteString(".") + out.WriteString(_bucketPartition.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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _bucketArn.Region, + }, + }) + return out + }(), + }, nil + } + } + if _UseFIPS == false { + if _UseDualStack == false { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_accessPointName) + out.WriteString("-") + out.WriteString(_bucketArn.AccountId) + out.WriteString(".") + out.WriteString(_url.Authority) + out.WriteString(_url.Path) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _bucketArn.Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + if _UseFIPS == false { + if _UseDualStack == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_accessPointName) + out.WriteString("-") + out.WriteString(_bucketArn.AccountId) + out.WriteString(".s3-accesspoint.") + out.WriteString(_bucketArn.Region) + out.WriteString(".") + out.WriteString(_bucketPartition.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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _bucketArn.Region, + }, + }) + return out + }(), + }, nil + } + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid ARN: The access point name may only contain a-z, A-Z, 0-9 and `-`. Found: `") + out.WriteString(_accessPointName) + out.WriteString("`") + return out.String() + }()) + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid ARN: The account id may only contain a-z, A-Z, 0-9 and `-`. Found: `") + out.WriteString(_bucketArn.AccountId) + out.WriteString("`") + return out.String() + }()) + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid ARN: The ARN was not for the S3 service, found: ") + out.WriteString(_bucketArn.Service) + return out.String() + }()) + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid region in ARN: `") + out.WriteString(_bucketArn.Region) + out.WriteString("` (invalid DNS name)") + return out.String() + }()) + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Client was configured for partition `") + out.WriteString(_partitionResult.Name) + out.WriteString("` but ARN (`") + out.WriteString(_Bucket) + out.WriteString("`) has `") + out.WriteString(_bucketPartition.Name) + out.WriteString("`") + return out.String() + }()) + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid ARN: The ARN may only contain a single resource component after `accesspoint`.") + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + if rulesfn.IsValidHostLabel(_accessPointName, true) { + if _UseDualStack == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "S3 MRAP does not support dual-stack") + } + if _UseFIPS == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "S3 MRAP does not support FIPS") + } + if _Accelerate == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "S3 MRAP does not support S3 Accelerate") + } + if _DisableMultiRegionAccessPoints == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid configuration: Multi-Region Access Point ARNs are disabled.") + } + if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { + _mrapPartition := *exprVal + _ = _mrapPartition + if _mrapPartition.Name == _bucketArn.Partition { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_accessPointName) + out.WriteString(".accesspoint.s3-global.") + out.WriteString(_mrapPartition.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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4a", + "signingName": "s3", + "signingRegionSet": []interface{}{ + "*", + }, + }, + }) + return out + }(), + }, nil + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Client was configured for partition `") + out.WriteString(_mrapPartition.Name) + out.WriteString("` but bucket referred to partition `") + out.WriteString(_bucketArn.Partition) + out.WriteString("`") + return out.String() + }()) + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Access Point Name") + } + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid ARN: Expected a resource of the format `accesspoint:` but no name was provided") + } + if _bucketArn.Service == "s3-outposts" { + if _UseDualStack == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "S3 Outposts does not support Dual-stack") + } + if _UseFIPS == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "S3 Outposts does not support FIPS") + } + if _Accelerate == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "S3 Outposts does not support S3 Accelerate") + } + if exprVal := _bucketArn.ResourceId.Get(4); exprVal != nil { + _var_244 := *exprVal + _ = _var_244 + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Arn: Outpost Access Point ARN contains sub resources") + } + if exprVal := _bucketArn.ResourceId.Get(1); exprVal != nil { + _outpostId := *exprVal + _ = _outpostId + if rulesfn.IsValidHostLabel(_outpostId, false) { + if exprVal := params.UseArnRegion; exprVal != nil { + _UseArnRegion := *exprVal + _ = _UseArnRegion + if _UseArnRegion == false { + if !(_bucketArn.Region == _Region) { + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid configuration: region from ARN `") + out.WriteString(_bucketArn.Region) + out.WriteString("` does not match client region `") + out.WriteString(_Region) + out.WriteString("` and UseArnRegion is `false`") + return out.String() + }()) + } + } + } + if exprVal := awsrulesfn.GetPartition(_bucketArn.Region); exprVal != nil { + _bucketPartition := *exprVal + _ = _bucketPartition + if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { + _partitionResult := *exprVal + _ = _partitionResult + if _bucketPartition.Name == _partitionResult.Name { + if rulesfn.IsValidHostLabel(_bucketArn.Region, true) { + if rulesfn.IsValidHostLabel(_bucketArn.AccountId, false) { + if exprVal := _bucketArn.ResourceId.Get(2); exprVal != nil { + _outpostType := *exprVal + _ = _outpostType + if exprVal := _bucketArn.ResourceId.Get(3); exprVal != nil { + _accessPointName := *exprVal + _ = _accessPointName + if _outpostType == "accesspoint" { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_accessPointName) + out.WriteString("-") + out.WriteString(_bucketArn.AccountId) + out.WriteString(".") + out.WriteString(_outpostId) + out.WriteString(".") + out.WriteString(_url.Authority) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3-outposts", + "signingRegion": _bucketArn.Region, + }, + }) + return out + }(), + }, nil + } + } + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_accessPointName) + out.WriteString("-") + out.WriteString(_bucketArn.AccountId) + out.WriteString(".") + out.WriteString(_outpostId) + out.WriteString(".s3-outposts.") + out.WriteString(_bucketArn.Region) + out.WriteString(".") + out.WriteString(_bucketPartition.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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3-outposts", + "signingRegion": _bucketArn.Region, + }, + }) + return out + }(), + }, nil + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Expected an outpost type `accesspoint`, found ") + out.WriteString(_outpostType) + return out.String() + }()) + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid ARN: expected an access point name") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid ARN: Expected a 4-component resource") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid ARN: The account id may only contain a-z, A-Z, 0-9 and `-`. Found: `") + out.WriteString(_bucketArn.AccountId) + out.WriteString("`") + return out.String() + }()) + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid region in ARN: `") + out.WriteString(_bucketArn.Region) + out.WriteString("` (invalid DNS name)") + return out.String() + }()) + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Client was configured for partition `") + out.WriteString(_partitionResult.Name) + out.WriteString("` but ARN (`") + out.WriteString(_Bucket) + out.WriteString("`) has `") + out.WriteString(_bucketPartition.Name) + out.WriteString("`") + return out.String() + }()) + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid ARN: The outpost Id may only contain a-z, A-Z, 0-9 and `-`. Found: `") + out.WriteString(_outpostId) + out.WriteString("`") + return out.String() + }()) + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid ARN: The Outpost Id was not set") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid ARN: Unrecognized format: ") + out.WriteString(_Bucket) + out.WriteString(" (type: ") + out.WriteString(_arnType) + out.WriteString(")") + return out.String() + }()) + } + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid ARN: No ARN type specified") + } + } + if exprVal := rulesfn.SubString(_Bucket, 0, 4, false); exprVal != nil { + _arnPrefix := *exprVal + _ = _arnPrefix + if _arnPrefix == "arn:" { + if !(awsrulesfn.ParseARN(_Bucket) != nil) { + return endpoint, fmt.Errorf("endpoint rule error, %s", func() string { + var out strings.Builder + out.WriteString("Invalid ARN: `") + out.WriteString(_Bucket) + out.WriteString("` was not a valid ARN") + return out.String() + }()) + } + } + } + if _ForcePathStyle == true { + if exprVal := awsrulesfn.ParseARN(_Bucket); exprVal != nil { + _var_257 := *exprVal + _ = _var_257 + return endpoint, fmt.Errorf("endpoint rule error, %s", "Path-style addressing cannot be used with ARN buckets") + } + } + _uri_encoded_bucket := rulesfn.URIEncode(_Bucket) + _ = _uri_encoded_bucket + if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { + _partitionResult := *exprVal + _ = _partitionResult + if _Accelerate == false { + if _UseDualStack == true { + if !(params.Endpoint != nil) { + if _UseFIPS == true { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3-fips.dualstack.us-east-1.") + out.WriteString(_partitionResult.DnsSuffix) + out.WriteString("/") + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + if _UseDualStack == true { + if !(params.Endpoint != nil) { + if _UseFIPS == true { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3-fips.dualstack.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_partitionResult.DnsSuffix) + out.WriteString("/") + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseDualStack == true { + if !(params.Endpoint != nil) { + if _UseFIPS == true { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3-fips.dualstack.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_partitionResult.DnsSuffix) + out.WriteString("/") + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseDualStack == false { + if !(params.Endpoint != nil) { + if _UseFIPS == true { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3-fips.us-east-1.") + out.WriteString(_partitionResult.DnsSuffix) + out.WriteString("/") + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + if _UseDualStack == false { + if !(params.Endpoint != nil) { + if _UseFIPS == true { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3-fips.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_partitionResult.DnsSuffix) + out.WriteString("/") + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseDualStack == false { + if !(params.Endpoint != nil) { + if _UseFIPS == true { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3-fips.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_partitionResult.DnsSuffix) + out.WriteString("/") + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseDualStack == true { + if !(params.Endpoint != nil) { + if _UseFIPS == false { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3.dualstack.us-east-1.") + out.WriteString(_partitionResult.DnsSuffix) + out.WriteString("/") + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + if _UseDualStack == true { + if !(params.Endpoint != nil) { + if _UseFIPS == false { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3.dualstack.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_partitionResult.DnsSuffix) + out.WriteString("/") + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseDualStack == true { + if !(params.Endpoint != nil) { + if _UseFIPS == false { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3.dualstack.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_partitionResult.DnsSuffix) + out.WriteString("/") + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseDualStack == false { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + if _UseFIPS == false { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_url.Authority) + out.WriteString(_url.NormalizedPath) + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseDualStack == false { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + if _UseFIPS == false { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + if _Region == "us-east-1" { + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_url.Authority) + out.WriteString(_url.NormalizedPath) + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_url.Authority) + out.WriteString(_url.NormalizedPath) + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseDualStack == false { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + if _UseFIPS == false { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_url.Authority) + out.WriteString(_url.NormalizedPath) + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseDualStack == false { + if !(params.Endpoint != nil) { + if _UseFIPS == false { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3.") + out.WriteString(_partitionResult.DnsSuffix) + out.WriteString("/") + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + if _UseDualStack == false { + if !(params.Endpoint != nil) { + if _UseFIPS == false { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + if _Region == "us-east-1" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3.") + out.WriteString(_partitionResult.DnsSuffix) + out.WriteString("/") + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_partitionResult.DnsSuffix) + out.WriteString("/") + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseDualStack == false { + if !(params.Endpoint != nil) { + if _UseFIPS == false { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_partitionResult.DnsSuffix) + out.WriteString("/") + out.WriteString(_uri_encoded_bucket) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Path-style addressing cannot be used with S3 Accelerate") + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + if exprVal := params.UseObjectLambdaEndpoint; exprVal != nil { + _UseObjectLambdaEndpoint := *exprVal + _ = _UseObjectLambdaEndpoint + if _UseObjectLambdaEndpoint == true { + if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { + _partitionResult := *exprVal + _ = _partitionResult + if rulesfn.IsValidHostLabel(_Region, true) { + if _UseDualStack == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "S3 Object Lambda does not support Dual-stack") + } + if _Accelerate == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "S3 Object Lambda does not support S3 Accelerate") + } + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_url.Authority) + out.WriteString(_url.Path) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3-object-lambda", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + if _UseFIPS == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3-object-lambda-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{}, + Properties: func() smithy.Properties { + var out smithy.Properties + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3-object-lambda", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3-object-lambda.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3-object-lambda", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid region: region was not a valid DNS name.") + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + } + if !(params.Bucket != nil) { + if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { + _partitionResult := *exprVal + _ = _partitionResult + if rulesfn.IsValidHostLabel(_Region, true) { + if _UseFIPS == true { + if _UseDualStack == true { + if !(params.Endpoint != nil) { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3-fips.dualstack.us-east-1.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + if _UseFIPS == true { + if _UseDualStack == true { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3-fips.dualstack.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseFIPS == true { + if _UseDualStack == true { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3-fips.dualstack.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseFIPS == true { + if _UseDualStack == false { + if !(params.Endpoint != nil) { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3-fips.us-east-1.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + if _UseFIPS == true { + if _UseDualStack == false { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3-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{}, + Properties: func() smithy.Properties { + var out smithy.Properties + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseFIPS == true { + if _UseDualStack == false { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3-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{}, + Properties: func() smithy.Properties { + var out smithy.Properties + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseFIPS == false { + if _UseDualStack == true { + if !(params.Endpoint != nil) { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3.dualstack.us-east-1.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + if _UseFIPS == false { + if _UseDualStack == true { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3.dualstack.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseFIPS == false { + if _UseDualStack == true { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3.dualstack.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseFIPS == false { + if _UseDualStack == false { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_url.Authority) + out.WriteString(_url.Path) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseFIPS == false { + if _UseDualStack == false { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + if _Region == "us-east-1" { + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_url.Authority) + out.WriteString(_url.Path) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_url.Authority) + out.WriteString(_url.Path) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseFIPS == false { + if _UseDualStack == false { + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if exprVal := rulesfn.ParseURL(_Endpoint); exprVal != nil { + _url := *exprVal + _ = _url + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString(_url.Scheme) + out.WriteString("://") + out.WriteString(_url.Authority) + out.WriteString(_url.Path) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + } + if _UseFIPS == false { + if _UseDualStack == false { + if !(params.Endpoint != nil) { + if _Region == "aws-global" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": "us-east-1", + }, + }) + return out + }(), + }, nil + } + } + } + } + if _UseFIPS == false { + if _UseDualStack == false { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == true { + if _Region == "us-east-1" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + if _UseFIPS == false { + if _UseDualStack == false { + if !(params.Endpoint != nil) { + if !(_Region == "aws-global") { + if _UseGlobalEndpoint == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://s3.") + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "disableDoubleEncoding": true, + "name": "sigv4", + "signingName": "s3", + "signingRegion": _Region, + }, + }) + return out + }(), + }, nil + } + } + } + } + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid region: region was not a valid DNS name.") + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "A region must be set when sending requests to S3.") +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/generated.json index 8643d42ff..414c8124f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/generated.json @@ -9,7 +9,8 @@ "github.com/aws/aws-sdk-go-v2/service/internal/checksum": "v0.0.0-00010101000000-000000000000", "github.com/aws/aws-sdk-go-v2/service/internal/presigned-url": "v1.0.7", "github.com/aws/aws-sdk-go-v2/service/internal/s3shared": "v1.2.3", - "github.com/aws/smithy-go": "v1.4.0" + "github.com/aws/smithy-go": "v1.4.0", + "github.com/google/go-cmp": "v0.5.4" }, "files": [ "api_client.go", @@ -110,6 +111,7 @@ "deserializers.go", "doc.go", "endpoints.go", + "endpoints_test.go", "eventstream.go", "generated.json", "internal/endpoints/endpoints.go", diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/go_module_metadata.go index a79184177..667ff71e4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/go_module_metadata.go @@ -3,4 +3,4 @@ package s3 // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.27.11" +const goModuleVersion = "1.40.0" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/handwritten_paginators.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/handwritten_paginators.go new file mode 100644 index 000000000..3d0b25100 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/handwritten_paginators.go @@ -0,0 +1,204 @@ +package s3 + +import ( + "context" + "fmt" +) + +// ListObjectVersionsAPIClient is a client that implements the ListObjectVersions +// operation +type ListObjectVersionsAPIClient interface { + ListObjectVersions(context.Context, *ListObjectVersionsInput, ...func(*Options)) (*ListObjectVersionsOutput, error) +} + +var _ ListObjectVersionsAPIClient = (*Client)(nil) + +// ListObjectVersionsPaginatorOptions is the paginator options for ListObjectVersions +type ListObjectVersionsPaginatorOptions struct { + // (Optional) The maximum number of Object Versions that you want Amazon S3 to + // return. + 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 +} + +// ListObjectVersionsPaginator is a paginator for ListObjectVersions +type ListObjectVersionsPaginator struct { + options ListObjectVersionsPaginatorOptions + client ListObjectVersionsAPIClient + params *ListObjectVersionsInput + firstPage bool + keyMarker *string + versionIDMarker *string + isTruncated bool +} + +// NewListObjectVersionsPaginator returns a new ListObjectVersionsPaginator +func NewListObjectVersionsPaginator(client ListObjectVersionsAPIClient, params *ListObjectVersionsInput, optFns ...func(*ListObjectVersionsPaginatorOptions)) *ListObjectVersionsPaginator { + if params == nil { + params = &ListObjectVersionsInput{} + } + + options := ListObjectVersionsPaginatorOptions{} + options.Limit = params.MaxKeys + + for _, fn := range optFns { + fn(&options) + } + + return &ListObjectVersionsPaginator{ + options: options, + client: client, + params: params, + firstPage: true, + keyMarker: params.KeyMarker, + versionIDMarker: params.VersionIdMarker, + } +} + +// HasMorePages returns a boolean indicating whether more pages are available +func (p *ListObjectVersionsPaginator) HasMorePages() bool { + return p.firstPage || p.isTruncated +} + +// NextPage retrieves the next ListObjectVersions page. +func (p *ListObjectVersionsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListObjectVersionsOutput, error) { + if !p.HasMorePages() { + return nil, fmt.Errorf("no more pages available") + } + + params := *p.params + params.KeyMarker = p.keyMarker + params.VersionIdMarker = p.versionIDMarker + + var limit int32 + if p.options.Limit > 0 { + limit = p.options.Limit + } + params.MaxKeys = limit + + result, err := p.client.ListObjectVersions(ctx, ¶ms, optFns...) + if err != nil { + return nil, err + } + p.firstPage = false + + prevToken := p.keyMarker + p.isTruncated = result.IsTruncated + p.keyMarker = nil + p.versionIDMarker = nil + if result.IsTruncated { + p.keyMarker = result.NextKeyMarker + p.versionIDMarker = result.NextVersionIdMarker + } + + if p.options.StopOnDuplicateToken && + prevToken != nil && + p.keyMarker != nil && + *prevToken == *p.keyMarker { + p.isTruncated = false + } + + return result, nil +} + +// ListMultipartUploadsAPIClient is a client that implements the ListMultipartUploads +// operation +type ListMultipartUploadsAPIClient interface { + ListMultipartUploads(context.Context, *ListMultipartUploadsInput, ...func(*Options)) (*ListMultipartUploadsOutput, error) +} + +var _ ListMultipartUploadsAPIClient = (*Client)(nil) + +// ListMultipartUploadsPaginatorOptions is the paginator options for ListMultipartUploads +type ListMultipartUploadsPaginatorOptions struct { + // (Optional) The maximum number of Multipart Uploads that you want Amazon S3 to + // return. + 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 +} + +// ListMultipartUploadsPaginator is a paginator for ListMultipartUploads +type ListMultipartUploadsPaginator struct { + options ListMultipartUploadsPaginatorOptions + client ListMultipartUploadsAPIClient + params *ListMultipartUploadsInput + firstPage bool + keyMarker *string + uploadIDMarker *string + isTruncated bool +} + +// NewListMultipartUploadsPaginator returns a new ListMultipartUploadsPaginator +func NewListMultipartUploadsPaginator(client ListMultipartUploadsAPIClient, params *ListMultipartUploadsInput, optFns ...func(*ListMultipartUploadsPaginatorOptions)) *ListMultipartUploadsPaginator { + if params == nil { + params = &ListMultipartUploadsInput{} + } + + options := ListMultipartUploadsPaginatorOptions{} + options.Limit = params.MaxUploads + + for _, fn := range optFns { + fn(&options) + } + + return &ListMultipartUploadsPaginator{ + options: options, + client: client, + params: params, + firstPage: true, + keyMarker: params.KeyMarker, + uploadIDMarker: params.UploadIdMarker, + } +} + +// HasMorePages returns a boolean indicating whether more pages are available +func (p *ListMultipartUploadsPaginator) HasMorePages() bool { + return p.firstPage || p.isTruncated +} + +// NextPage retrieves the next ListMultipartUploads page. +func (p *ListMultipartUploadsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListMultipartUploadsOutput, error) { + if !p.HasMorePages() { + return nil, fmt.Errorf("no more pages available") + } + + params := *p.params + params.KeyMarker = p.keyMarker + params.UploadIdMarker = p.uploadIDMarker + + var limit int32 + if p.options.Limit > 0 { + limit = p.options.Limit + } + params.MaxUploads = limit + + result, err := p.client.ListMultipartUploads(ctx, ¶ms, optFns...) + if err != nil { + return nil, err + } + p.firstPage = false + + prevToken := p.keyMarker + p.isTruncated = result.IsTruncated + p.keyMarker = nil + p.uploadIDMarker = nil + if result.IsTruncated { + p.keyMarker = result.NextKeyMarker + p.uploadIDMarker = result.NextUploadIdMarker + } + + if p.options.StopOnDuplicateToken && + prevToken != nil && + p.keyMarker != nil && + *prevToken == *p.keyMarker { + p.isTruncated = false + } + + return result, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/doc.go index 9a392d120..e1d1cbefa 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/doc.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/doc.go @@ -46,7 +46,6 @@ an request is serialized, and removes the serialized bucket name from request pa Middleware layering: - Initialize : HTTP Request -> ARN Lookup -> Input-Validation -> Serialize step Serialize : HTTP Request -> Process ARN -> operation serializer -> Update-Endpoint customization -> Remove-Bucket -> next middleware diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/process_arn_resource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/process_arn_resource.go index a232e622b..bbc971f2a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/process_arn_resource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/process_arn_resource.go @@ -50,6 +50,10 @@ func (m *processARNResource) HandleSerialize( ) ( out middleware.SerializeOutput, metadata middleware.Metadata, err error, ) { + if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) { + return next.HandleSerialize(ctx, in) + } + // check if arn was provided, if not skip this middleware arnValue, ok := s3shared.GetARNResourceFromContext(ctx) if !ok { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/remove_bucket_middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/remove_bucket_middleware.go index 2e030f29c..cf3f4dc8b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/remove_bucket_middleware.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/remove_bucket_middleware.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/transport/http" ) @@ -21,6 +22,10 @@ func (m *removeBucketFromPathMiddleware) HandleSerialize( ) ( out middleware.SerializeOutput, metadata middleware.Metadata, err error, ) { + if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) { + return next.HandleSerialize(ctx, in) + } + // check if a bucket removal from HTTP path is required bucket, ok := getRemoveBucketFromPath(ctx) if !ok { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/s3_object_lambda.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/s3_object_lambda.go index 325b2d369..6e1d44724 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/s3_object_lambda.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/s3_object_lambda.go @@ -30,6 +30,10 @@ func (t *s3ObjectLambdaEndpoint) HandleSerialize( ) ( out middleware.SerializeOutput, metadata middleware.Metadata, err error, ) { + if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) { + return next.HandleSerialize(ctx, in) + } + if !t.UseEndpoint { return next.HandleSerialize(ctx, in) } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/signer_wrapper.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/signer_wrapper.go index 6689acb8e..4408f3e8a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/signer_wrapper.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/signer_wrapper.go @@ -3,6 +3,7 @@ package customizations import ( "context" "fmt" + "strings" "github.com/aws/aws-sdk-go-v2/aws" v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" @@ -83,8 +84,8 @@ func (s *SignHTTPRequestMiddleware) HandleFinalize(ctx context.Context, in middl // fetch signer type from context signerVersion := GetSignerVersion(ctx) - switch signerVersion { - case v4a.Version: + // SigV4a + if strings.EqualFold(signerVersion, v4a.Version) { v4aCredentialProvider, ok := s.credentialsProvider.(v4a.CredentialsProvider) if !ok { return out, metadata, fmt.Errorf("invalid credential-provider provided for sigV4a Signer") @@ -96,15 +97,14 @@ func (s *SignHTTPRequestMiddleware) HandleFinalize(ctx context.Context, in middl LogSigning: s.logSigning, }) return mw.HandleFinalize(ctx, in, next) - - default: - mw := v4.NewSignHTTPRequestMiddleware(v4.SignHTTPRequestMiddlewareOptions{ - CredentialsProvider: s.credentialsProvider, - Signer: s.v4Signer, - LogSigning: s.logSigning, - }) - return mw.HandleFinalize(ctx, in, next) } + // SigV4 + mw := v4.NewSignHTTPRequestMiddleware(v4.SignHTTPRequestMiddlewareOptions{ + CredentialsProvider: s.credentialsProvider, + Signer: s.v4Signer, + LogSigning: s.logSigning, + }) + return mw.HandleFinalize(ctx, in, next) } // RegisterSigningMiddleware registers the wrapper signing middleware to the stack. If a signing middleware is already diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/update_endpoint.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/update_endpoint.go index e5f95254a..eedfc7eef 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/update_endpoint.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/customizations/update_endpoint.go @@ -69,9 +69,9 @@ func UpdateEndpoint(stack *middleware.Stack, options UpdateEndpointOptions) (err const serializerID = "OperationSerializer" // initial arn look up middleware - err = stack.Initialize.Add(&s3shared.ARNLookup{ + err = stack.Initialize.Insert(&s3shared.ARNLookup{ GetARNValue: options.Accessor.GetBucketFromInput, - }, middleware.Before) + }, "legacyEndpointContextSetter", middleware.After) if err != nil { return err } @@ -141,6 +141,10 @@ func (u *updateEndpoint) HandleSerialize( ) ( out middleware.SerializeOutput, metadata middleware.Metadata, err error, ) { + if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) { + return next.HandleSerialize(ctx, in) + } + // if arn was processed, skip this middleware if _, ok := s3shared.GetARNResourceFromContext(ctx); ok { return next.HandleSerialize(ctx, in) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/endpoints/endpoints.go index 4b8457ebf..c7e5f6d2b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/endpoints/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/internal/endpoints/endpoints.go @@ -91,13 +91,17 @@ var partitionRegexp = struct { 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)\\-\\w+\\-\\d+$"), + Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il)\\-\\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+$"), } @@ -195,6 +199,15 @@ var defaultPartitions = endpoints.Partitions{ }: { Hostname: "s3.dualstack.ap-south-1.amazonaws.com", }, + endpoints.EndpointKey{ + Region: "ap-south-2", + }: endpoints.Endpoint{}, + endpoints.EndpointKey{ + Region: "ap-south-2", + Variant: endpoints.DualStackVariant, + }: { + Hostname: "s3.dualstack.ap-south-2.amazonaws.com", + }, endpoints.EndpointKey{ Region: "ap-southeast-1", }: endpoints.Endpoint{ @@ -230,6 +243,15 @@ var defaultPartitions = endpoints.Partitions{ }: { Hostname: "s3.dualstack.ap-southeast-3.amazonaws.com", }, + endpoints.EndpointKey{ + Region: "ap-southeast-4", + }: endpoints.Endpoint{}, + endpoints.EndpointKey{ + Region: "ap-southeast-4", + Variant: endpoints.DualStackVariant, + }: { + Hostname: "s3.dualstack.ap-southeast-4.amazonaws.com", + }, endpoints.EndpointKey{ Region: "aws-global", }: endpoints.Endpoint{ @@ -269,6 +291,15 @@ var defaultPartitions = endpoints.Partitions{ }: { Hostname: "s3.dualstack.eu-central-1.amazonaws.com", }, + endpoints.EndpointKey{ + Region: "eu-central-2", + }: endpoints.Endpoint{}, + endpoints.EndpointKey{ + Region: "eu-central-2", + Variant: endpoints.DualStackVariant, + }: { + Hostname: "s3.dualstack.eu-central-2.amazonaws.com", + }, endpoints.EndpointKey{ Region: "eu-north-1", }: endpoints.Endpoint{}, @@ -287,6 +318,15 @@ var defaultPartitions = endpoints.Partitions{ }: { Hostname: "s3.dualstack.eu-south-1.amazonaws.com", }, + endpoints.EndpointKey{ + Region: "eu-south-2", + }: endpoints.Endpoint{}, + endpoints.EndpointKey{ + Region: "eu-south-2", + Variant: endpoints.DualStackVariant, + }: { + Hostname: "s3.dualstack.eu-south-2.amazonaws.com", + }, endpoints.EndpointKey{ Region: "eu-west-1", }: endpoints.Endpoint{ @@ -363,6 +403,15 @@ var defaultPartitions = endpoints.Partitions{ }, Deprecated: aws.TrueTernary, }, + endpoints.EndpointKey{ + Region: "il-central-1", + }: endpoints.Endpoint{}, + endpoints.EndpointKey{ + Region: "il-central-1", + Variant: endpoints.DualStackVariant, + }: { + Hostname: "s3.dualstack.il-central-1.amazonaws.com", + }, endpoints.EndpointKey{ Region: "me-central-1", }: endpoints.Endpoint{}, @@ -620,6 +669,48 @@ var defaultPartitions = endpoints.Partitions{ }: endpoints.Endpoint{}, }, }, + { + ID: "aws-iso-e", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "s3-fips.{region}.cloud.adc-e.uk", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "s3.{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: "s3-fips.{region}.csp.hci.ic.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "s3.{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{ @@ -785,6 +876,32 @@ func GetDNSSuffix(id string, options Options) (string, error) { } + case strings.EqualFold(id, "aws-iso-e"): + switch variant { + case endpoints.FIPSVariant: + return "cloud.adc-e.uk", nil + + case 0: + return "cloud.adc-e.uk", nil + + default: + return "", fmt.Errorf("unsupported endpoint variant %v, in partition %s", variant, id) + + } + + case strings.EqualFold(id, "aws-iso-f"): + switch variant { + case endpoints.FIPSVariant: + return "csp.hci.ic.gov", nil + + case 0: + return "csp.hci.ic.gov", nil + + default: + return "", fmt.Errorf("unsupported endpoint variant %v, in partition %s", variant, id) + + } + case strings.EqualFold(id, "aws-us-gov"): switch variant { case endpoints.DualStackVariant: @@ -826,6 +943,12 @@ func GetDNSSuffixFromRegion(region string, options Options) (string, error) { case partitionRegexp.AwsIsoB.MatchString(region): return GetDNSSuffix("aws-iso-b", options) + case partitionRegexp.AwsIsoE.MatchString(region): + return GetDNSSuffix("aws-iso-e", options) + + case partitionRegexp.AwsIsoF.MatchString(region): + return GetDNSSuffix("aws-iso-f", options) + case partitionRegexp.AwsUsGov.MatchString(region): return GetDNSSuffix("aws-us-gov", options) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/serialize_immutable_hostname_bucket.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/serialize_immutable_hostname_bucket.go new file mode 100644 index 000000000..cb22779fb --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/serialize_immutable_hostname_bucket.go @@ -0,0 +1,72 @@ +package s3 + +import ( + "context" + "fmt" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + "path" + + "github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn" + smithy "github.com/aws/smithy-go" + "github.com/aws/smithy-go/encoding/httpbinding" + "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" +) + +// serializeImmutableHostnameBucketMiddleware handles injecting the bucket name into +// "immutable" hostnames resolved via v1 EndpointResolvers. This CANNOT be done in +// serialization, since v2 endpoint resolution requires removing the {Bucket} path +// segment from all S3 requests. +// +// This will only be done for non-ARN buckets, as the features that use those require +// virtualhost manipulation to function and we previously (pre-ep2) expected the caller +// to handle that in their resolver. +type serializeImmutableHostnameBucketMiddleware struct { + UsePathStyle bool +} + +func (*serializeImmutableHostnameBucketMiddleware) ID() string { + return "serializeImmutableHostnameBucket" +} + +func (m *serializeImmutableHostnameBucketMiddleware) 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, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} + } + if !smithyhttp.GetHostnameImmutable(ctx) && + !(awsmiddleware.GetRequiresLegacyEndpoints(ctx) && m.UsePathStyle) { + return next.HandleSerialize(ctx, in) + } + + bucket, ok := bucketFromInput(in.Parameters) + if !ok { + return next.HandleSerialize(ctx, in) + } + + parsedBucket := awsrulesfn.ParseARN(bucket) + + // disallow ARN buckets except for MRAP arns + if parsedBucket != nil && len(parsedBucket.Region) > 0 { + return next.HandleSerialize(ctx, in) + } + + request.URL.Path = path.Join(request.URL.Path, bucket) + request.URL.RawPath = path.Join(request.URL.RawPath, httpbinding.EscapePath(bucket, true)) + + return next.HandleSerialize(ctx, in) +} + +func addSerializeImmutableHostnameBucketMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert( + &serializeImmutableHostnameBucketMiddleware{ + UsePathStyle: options.UsePathStyle, + }, + "OperationSerializer", + middleware.Before, + ) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/serializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/serializers.go index 126dedcf3..463f6b706 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/serializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/serializers.go @@ -39,11 +39,18 @@ func (m *awsRestxml_serializeOpAbortMultipartUpload) HandleSerialize(ctx context return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?x-id=AbortMultipartUpload") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?x-id=AbortMultipartUpload") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -64,15 +71,6 @@ func awsRestxml_serializeOpHttpBindingsAbortMultipartUploadInput(v *AbortMultipa return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -120,11 +118,18 @@ func (m *awsRestxml_serializeOpCompleteMultipartUpload) HandleSerialize(ctx cont return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?x-id=CompleteMultipartUpload") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?x-id=CompleteMultipartUpload") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "POST" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -169,15 +174,6 @@ func awsRestxml_serializeOpHttpBindingsCompleteMultipartUploadInput(v *CompleteM return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ChecksumCRC32 != nil && len(*v.ChecksumCRC32) > 0 { locationName := "X-Amz-Checksum-Crc32" encoder.SetHeader(locationName).String(*v.ChecksumCRC32) @@ -260,11 +256,18 @@ func (m *awsRestxml_serializeOpCopyObject) HandleSerialize(ctx context.Context, return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?x-id=CopyObject") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?x-id=CopyObject") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -290,15 +293,6 @@ func awsRestxml_serializeOpHttpBindingsCopyObjectInput(v *CopyObjectInput, encod encoder.SetHeader(locationName).String(string(v.ACL)) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.BucketKeyEnabled { locationName := "X-Amz-Server-Side-Encryption-Bucket-Key-Enabled" encoder.SetHeader(locationName).Boolean(v.BucketKeyEnabled) @@ -526,11 +520,18 @@ func (m *awsRestxml_serializeOpCreateBucket) HandleSerialize(ctx context.Context return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}") + opPath, opQuery := httpbinding.SplitURI("/") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -580,15 +581,6 @@ func awsRestxml_serializeOpHttpBindingsCreateBucketInput(v *CreateBucketInput, e encoder.SetHeader(locationName).String(string(v.ACL)) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.GrantFullControl != nil && len(*v.GrantFullControl) > 0 { locationName := "X-Amz-Grant-Full-Control" encoder.SetHeader(locationName).String(*v.GrantFullControl) @@ -648,11 +640,18 @@ func (m *awsRestxml_serializeOpCreateMultipartUpload) HandleSerialize(ctx contex return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?uploads&x-id=CreateMultipartUpload") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?uploads&x-id=CreateMultipartUpload") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "POST" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -678,15 +677,6 @@ func awsRestxml_serializeOpHttpBindingsCreateMultipartUploadInput(v *CreateMulti encoder.SetHeader(locationName).String(string(v.ACL)) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.BucketKeyEnabled { locationName := "X-Amz-Server-Side-Encryption-Bucket-Key-Enabled" encoder.SetHeader(locationName).Boolean(v.BucketKeyEnabled) @@ -859,11 +849,18 @@ func (m *awsRestxml_serializeOpDeleteBucket) HandleSerialize(ctx context.Context return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}") + opPath, opQuery := httpbinding.SplitURI("/") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -884,15 +881,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteBucketInput(v *DeleteBucketInput, e return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -922,11 +910,18 @@ func (m *awsRestxml_serializeOpDeleteBucketAnalyticsConfiguration) HandleSeriali return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?analytics") + opPath, opQuery := httpbinding.SplitURI("/?analytics") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -947,15 +942,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteBucketAnalyticsConfigurationInput(v return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -989,11 +975,18 @@ func (m *awsRestxml_serializeOpDeleteBucketCors) HandleSerialize(ctx context.Con return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?cors") + opPath, opQuery := httpbinding.SplitURI("/?cors") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1014,15 +1007,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteBucketCorsInput(v *DeleteBucketCors return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -1052,11 +1036,18 @@ func (m *awsRestxml_serializeOpDeleteBucketEncryption) HandleSerialize(ctx conte return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?encryption") + opPath, opQuery := httpbinding.SplitURI("/?encryption") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1077,15 +1068,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteBucketEncryptionInput(v *DeleteBuck return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -1115,11 +1097,18 @@ func (m *awsRestxml_serializeOpDeleteBucketIntelligentTieringConfiguration) Hand return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?intelligent-tiering") + opPath, opQuery := httpbinding.SplitURI("/?intelligent-tiering") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1140,15 +1129,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteBucketIntelligentTieringConfigurati return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.Id != nil { encoder.SetQuery("id").String(*v.Id) } @@ -1177,11 +1157,18 @@ func (m *awsRestxml_serializeOpDeleteBucketInventoryConfiguration) HandleSeriali return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?inventory") + opPath, opQuery := httpbinding.SplitURI("/?inventory") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1202,15 +1189,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteBucketInventoryConfigurationInput(v return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -1244,11 +1222,18 @@ func (m *awsRestxml_serializeOpDeleteBucketLifecycle) HandleSerialize(ctx contex return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?lifecycle") + opPath, opQuery := httpbinding.SplitURI("/?lifecycle") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1269,15 +1254,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteBucketLifecycleInput(v *DeleteBucke return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -1307,11 +1283,18 @@ func (m *awsRestxml_serializeOpDeleteBucketMetricsConfiguration) HandleSerialize return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?metrics") + opPath, opQuery := httpbinding.SplitURI("/?metrics") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1332,15 +1315,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteBucketMetricsConfigurationInput(v * return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -1374,11 +1348,18 @@ func (m *awsRestxml_serializeOpDeleteBucketOwnershipControls) HandleSerialize(ct return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?ownershipControls") + opPath, opQuery := httpbinding.SplitURI("/?ownershipControls") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1399,15 +1380,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteBucketOwnershipControlsInput(v *Del return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -1437,11 +1409,18 @@ func (m *awsRestxml_serializeOpDeleteBucketPolicy) HandleSerialize(ctx context.C return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?policy") + opPath, opQuery := httpbinding.SplitURI("/?policy") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1462,15 +1441,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteBucketPolicyInput(v *DeleteBucketPo return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -1500,11 +1470,18 @@ func (m *awsRestxml_serializeOpDeleteBucketReplication) HandleSerialize(ctx cont return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?replication") + opPath, opQuery := httpbinding.SplitURI("/?replication") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1525,15 +1502,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteBucketReplicationInput(v *DeleteBuc return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -1563,11 +1531,18 @@ func (m *awsRestxml_serializeOpDeleteBucketTagging) HandleSerialize(ctx context. return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?tagging") + opPath, opQuery := httpbinding.SplitURI("/?tagging") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1588,15 +1563,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteBucketTaggingInput(v *DeleteBucketT return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -1626,11 +1592,18 @@ func (m *awsRestxml_serializeOpDeleteBucketWebsite) HandleSerialize(ctx context. return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?website") + opPath, opQuery := httpbinding.SplitURI("/?website") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1651,15 +1624,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteBucketWebsiteInput(v *DeleteBucketW return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -1689,11 +1653,18 @@ func (m *awsRestxml_serializeOpDeleteObject) HandleSerialize(ctx context.Context return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?x-id=DeleteObject") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?x-id=DeleteObject") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1714,15 +1685,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteObjectInput(v *DeleteObjectInput, e return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.BypassGovernanceRetention { locationName := "X-Amz-Bypass-Governance-Retention" encoder.SetHeader(locationName).Boolean(v.BypassGovernanceRetention) @@ -1780,11 +1742,18 @@ func (m *awsRestxml_serializeOpDeleteObjects) HandleSerialize(ctx context.Contex return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?delete&x-id=DeleteObjects") + opPath, opQuery := httpbinding.SplitURI("/?delete&x-id=DeleteObjects") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "POST" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1829,15 +1798,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteObjectsInput(v *DeleteObjectsInput, return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.BypassGovernanceRetention { locationName := "X-Amz-Bypass-Governance-Retention" encoder.SetHeader(locationName).Boolean(v.BypassGovernanceRetention) @@ -1887,11 +1847,18 @@ func (m *awsRestxml_serializeOpDeleteObjectTagging) HandleSerialize(ctx context. return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?tagging") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?tagging") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1912,15 +1879,6 @@ func awsRestxml_serializeOpHttpBindingsDeleteObjectTaggingInput(v *DeleteObjectT return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -1963,11 +1921,18 @@ func (m *awsRestxml_serializeOpDeletePublicAccessBlock) HandleSerialize(ctx cont return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?publicAccessBlock") + opPath, opQuery := httpbinding.SplitURI("/?publicAccessBlock") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "DELETE" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -1988,15 +1953,6 @@ func awsRestxml_serializeOpHttpBindingsDeletePublicAccessBlockInput(v *DeletePub return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -2026,11 +1982,18 @@ func (m *awsRestxml_serializeOpGetBucketAccelerateConfiguration) HandleSerialize return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?accelerate") + opPath, opQuery := httpbinding.SplitURI("/?accelerate") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -2051,20 +2014,16 @@ func awsRestxml_serializeOpHttpBindingsGetBucketAccelerateConfigurationInput(v * return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) } + if len(v.RequestPayer) > 0 { + locationName := "X-Amz-Request-Payer" + encoder.SetHeader(locationName).String(string(v.RequestPayer)) + } + return nil } @@ -2089,11 +2048,18 @@ func (m *awsRestxml_serializeOpGetBucketAcl) HandleSerialize(ctx context.Context return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?acl") + opPath, opQuery := httpbinding.SplitURI("/?acl") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -2114,15 +2080,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketAclInput(v *GetBucketAclInput, e return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -2152,11 +2109,18 @@ func (m *awsRestxml_serializeOpGetBucketAnalyticsConfiguration) HandleSerialize( return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?analytics&x-id=GetBucketAnalyticsConfiguration") + opPath, opQuery := httpbinding.SplitURI("/?analytics&x-id=GetBucketAnalyticsConfiguration") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -2177,15 +2141,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketAnalyticsConfigurationInput(v *G return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -2219,11 +2174,18 @@ func (m *awsRestxml_serializeOpGetBucketCors) HandleSerialize(ctx context.Contex return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?cors") + opPath, opQuery := httpbinding.SplitURI("/?cors") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -2244,15 +2206,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketCorsInput(v *GetBucketCorsInput, return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -2282,11 +2235,18 @@ func (m *awsRestxml_serializeOpGetBucketEncryption) HandleSerialize(ctx context. return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?encryption") + opPath, opQuery := httpbinding.SplitURI("/?encryption") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -2307,15 +2267,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketEncryptionInput(v *GetBucketEncr return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -2345,11 +2296,18 @@ func (m *awsRestxml_serializeOpGetBucketIntelligentTieringConfiguration) HandleS return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?intelligent-tiering&x-id=GetBucketIntelligentTieringConfiguration") + opPath, opQuery := httpbinding.SplitURI("/?intelligent-tiering&x-id=GetBucketIntelligentTieringConfiguration") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -2370,15 +2328,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketIntelligentTieringConfigurationI return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.Id != nil { encoder.SetQuery("id").String(*v.Id) } @@ -2407,11 +2356,18 @@ func (m *awsRestxml_serializeOpGetBucketInventoryConfiguration) HandleSerialize( return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?inventory&x-id=GetBucketInventoryConfiguration") + opPath, opQuery := httpbinding.SplitURI("/?inventory&x-id=GetBucketInventoryConfiguration") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -2432,15 +2388,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketInventoryConfigurationInput(v *G return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -2474,11 +2421,18 @@ func (m *awsRestxml_serializeOpGetBucketLifecycleConfiguration) HandleSerialize( return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?lifecycle") + opPath, opQuery := httpbinding.SplitURI("/?lifecycle") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -2499,15 +2453,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketLifecycleConfigurationInput(v *G return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -2537,11 +2482,18 @@ func (m *awsRestxml_serializeOpGetBucketLocation) HandleSerialize(ctx context.Co return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?location") + opPath, opQuery := httpbinding.SplitURI("/?location") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -2562,15 +2514,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketLocationInput(v *GetBucketLocati return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -2600,12 +2543,19 @@ func (m *awsRestxml_serializeOpGetBucketLogging) HandleSerialize(ctx context.Con return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?logging") + opPath, opQuery := httpbinding.SplitURI("/?logging") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { + 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} } @@ -2625,15 +2575,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketLoggingInput(v *GetBucketLogging return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -2663,11 +2604,18 @@ func (m *awsRestxml_serializeOpGetBucketMetricsConfiguration) HandleSerialize(ct return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?metrics&x-id=GetBucketMetricsConfiguration") + opPath, opQuery := httpbinding.SplitURI("/?metrics&x-id=GetBucketMetricsConfiguration") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -2688,15 +2636,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketMetricsConfigurationInput(v *Get return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -2730,11 +2669,18 @@ func (m *awsRestxml_serializeOpGetBucketNotificationConfiguration) HandleSeriali return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?notification") + opPath, opQuery := httpbinding.SplitURI("/?notification") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -2755,15 +2701,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketNotificationConfigurationInput(v return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -2793,11 +2730,18 @@ func (m *awsRestxml_serializeOpGetBucketOwnershipControls) HandleSerialize(ctx c return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?ownershipControls") + opPath, opQuery := httpbinding.SplitURI("/?ownershipControls") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -2818,15 +2762,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketOwnershipControlsInput(v *GetBuc return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -2856,11 +2791,18 @@ func (m *awsRestxml_serializeOpGetBucketPolicy) HandleSerialize(ctx context.Cont return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?policy") + opPath, opQuery := httpbinding.SplitURI("/?policy") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -2881,15 +2823,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketPolicyInput(v *GetBucketPolicyIn return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -2919,11 +2852,18 @@ func (m *awsRestxml_serializeOpGetBucketPolicyStatus) HandleSerialize(ctx contex return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?policyStatus") + opPath, opQuery := httpbinding.SplitURI("/?policyStatus") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -2944,15 +2884,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketPolicyStatusInput(v *GetBucketPo return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -2982,11 +2913,18 @@ func (m *awsRestxml_serializeOpGetBucketReplication) HandleSerialize(ctx context return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?replication") + opPath, opQuery := httpbinding.SplitURI("/?replication") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -3007,15 +2945,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketReplicationInput(v *GetBucketRep return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -3045,11 +2974,18 @@ func (m *awsRestxml_serializeOpGetBucketRequestPayment) HandleSerialize(ctx cont return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?requestPayment") + opPath, opQuery := httpbinding.SplitURI("/?requestPayment") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -3070,15 +3006,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketRequestPaymentInput(v *GetBucket return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -3108,11 +3035,18 @@ func (m *awsRestxml_serializeOpGetBucketTagging) HandleSerialize(ctx context.Con return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?tagging") + opPath, opQuery := httpbinding.SplitURI("/?tagging") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -3133,15 +3067,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketTaggingInput(v *GetBucketTagging return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -3171,11 +3096,18 @@ func (m *awsRestxml_serializeOpGetBucketVersioning) HandleSerialize(ctx context. return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?versioning") + opPath, opQuery := httpbinding.SplitURI("/?versioning") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -3196,15 +3128,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketVersioningInput(v *GetBucketVers return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -3234,11 +3157,18 @@ func (m *awsRestxml_serializeOpGetBucketWebsite) HandleSerialize(ctx context.Con return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?website") + opPath, opQuery := httpbinding.SplitURI("/?website") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -3259,15 +3189,6 @@ func awsRestxml_serializeOpHttpBindingsGetBucketWebsiteInput(v *GetBucketWebsite return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -3297,11 +3218,18 @@ func (m *awsRestxml_serializeOpGetObject) HandleSerialize(ctx context.Context, i return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?x-id=GetObject") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?x-id=GetObject") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -3322,15 +3250,6 @@ func awsRestxml_serializeOpHttpBindingsGetObjectInput(v *GetObjectInput, encoder return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumMode) > 0 { locationName := "X-Amz-Checksum-Mode" encoder.SetHeader(locationName).String(string(v.ChecksumMode)) @@ -3451,11 +3370,18 @@ func (m *awsRestxml_serializeOpGetObjectAcl) HandleSerialize(ctx context.Context return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?acl") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?acl") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -3476,15 +3402,6 @@ func awsRestxml_serializeOpHttpBindingsGetObjectAclInput(v *GetObjectAclInput, e return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -3532,11 +3449,18 @@ func (m *awsRestxml_serializeOpGetObjectAttributes) HandleSerialize(ctx context. return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?attributes") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?attributes") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -3557,15 +3481,6 @@ func awsRestxml_serializeOpHttpBindingsGetObjectAttributesInput(v *GetObjectAttr return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -3652,11 +3567,18 @@ func (m *awsRestxml_serializeOpGetObjectLegalHold) HandleSerialize(ctx context.C return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?legal-hold") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?legal-hold") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -3677,15 +3599,6 @@ func awsRestxml_serializeOpHttpBindingsGetObjectLegalHoldInput(v *GetObjectLegal return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -3733,11 +3646,18 @@ func (m *awsRestxml_serializeOpGetObjectLockConfiguration) HandleSerialize(ctx c return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?object-lock") + opPath, opQuery := httpbinding.SplitURI("/?object-lock") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -3758,15 +3678,6 @@ func awsRestxml_serializeOpHttpBindingsGetObjectLockConfigurationInput(v *GetObj return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -3796,11 +3707,18 @@ func (m *awsRestxml_serializeOpGetObjectRetention) HandleSerialize(ctx context.C return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?retention") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?retention") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -3821,15 +3739,6 @@ func awsRestxml_serializeOpHttpBindingsGetObjectRetentionInput(v *GetObjectReten return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -3877,11 +3786,18 @@ func (m *awsRestxml_serializeOpGetObjectTagging) HandleSerialize(ctx context.Con return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?tagging") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?tagging") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -3902,15 +3818,6 @@ func awsRestxml_serializeOpHttpBindingsGetObjectTaggingInput(v *GetObjectTagging return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -3958,11 +3865,18 @@ func (m *awsRestxml_serializeOpGetObjectTorrent) HandleSerialize(ctx context.Con return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?torrent") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?torrent") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -3983,15 +3897,6 @@ func awsRestxml_serializeOpHttpBindingsGetObjectTorrentInput(v *GetObjectTorrent return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -4035,11 +3940,18 @@ func (m *awsRestxml_serializeOpGetPublicAccessBlock) HandleSerialize(ctx context return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?publicAccessBlock") + opPath, opQuery := httpbinding.SplitURI("/?publicAccessBlock") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -4060,15 +3972,6 @@ func awsRestxml_serializeOpHttpBindingsGetPublicAccessBlockInput(v *GetPublicAcc return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -4098,11 +4001,18 @@ func (m *awsRestxml_serializeOpHeadBucket) HandleSerialize(ctx context.Context, return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}") + opPath, opQuery := httpbinding.SplitURI("/") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "HEAD" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -4123,15 +4033,6 @@ func awsRestxml_serializeOpHttpBindingsHeadBucketInput(v *HeadBucketInput, encod return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -4161,11 +4062,18 @@ func (m *awsRestxml_serializeOpHeadObject) HandleSerialize(ctx context.Context, return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}") + opPath, opQuery := httpbinding.SplitURI("/{Key+}") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "HEAD" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -4186,15 +4094,6 @@ func awsRestxml_serializeOpHttpBindingsHeadObjectInput(v *HeadObjectInput, encod return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumMode) > 0 { locationName := "X-Amz-Checksum-Mode" encoder.SetHeader(locationName).String(string(v.ChecksumMode)) @@ -4291,11 +4190,18 @@ func (m *awsRestxml_serializeOpListBucketAnalyticsConfigurations) HandleSerializ return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?analytics&x-id=ListBucketAnalyticsConfigurations") + opPath, opQuery := httpbinding.SplitURI("/?analytics&x-id=ListBucketAnalyticsConfigurations") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -4316,15 +4222,6 @@ func awsRestxml_serializeOpHttpBindingsListBucketAnalyticsConfigurationsInput(v return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ContinuationToken != nil { encoder.SetQuery("continuation-token").String(*v.ContinuationToken) } @@ -4358,11 +4255,18 @@ func (m *awsRestxml_serializeOpListBucketIntelligentTieringConfigurations) Handl return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?intelligent-tiering&x-id=ListBucketIntelligentTieringConfigurations") + opPath, opQuery := httpbinding.SplitURI("/?intelligent-tiering&x-id=ListBucketIntelligentTieringConfigurations") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -4383,15 +4287,6 @@ func awsRestxml_serializeOpHttpBindingsListBucketIntelligentTieringConfiguration return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ContinuationToken != nil { encoder.SetQuery("continuation-token").String(*v.ContinuationToken) } @@ -4420,11 +4315,18 @@ func (m *awsRestxml_serializeOpListBucketInventoryConfigurations) HandleSerializ return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?inventory&x-id=ListBucketInventoryConfigurations") + opPath, opQuery := httpbinding.SplitURI("/?inventory&x-id=ListBucketInventoryConfigurations") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -4445,15 +4347,6 @@ func awsRestxml_serializeOpHttpBindingsListBucketInventoryConfigurationsInput(v return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ContinuationToken != nil { encoder.SetQuery("continuation-token").String(*v.ContinuationToken) } @@ -4487,11 +4380,18 @@ func (m *awsRestxml_serializeOpListBucketMetricsConfigurations) HandleSerialize( return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?metrics&x-id=ListBucketMetricsConfigurations") + opPath, opQuery := httpbinding.SplitURI("/?metrics&x-id=ListBucketMetricsConfigurations") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -4512,15 +4412,6 @@ func awsRestxml_serializeOpHttpBindingsListBucketMetricsConfigurationsInput(v *L return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ContinuationToken != nil { encoder.SetQuery("continuation-token").String(*v.ContinuationToken) } @@ -4558,7 +4449,14 @@ func (m *awsRestxml_serializeOpListBuckets) HandleSerialize(ctx context.Context, request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -4599,11 +4497,18 @@ func (m *awsRestxml_serializeOpListMultipartUploads) HandleSerialize(ctx context return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?uploads") + opPath, opQuery := httpbinding.SplitURI("/?uploads") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -4624,15 +4529,6 @@ func awsRestxml_serializeOpHttpBindingsListMultipartUploadsInput(v *ListMultipar return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.Delimiter != nil { encoder.SetQuery("delimiter").String(*v.Delimiter) } @@ -4658,6 +4554,11 @@ func awsRestxml_serializeOpHttpBindingsListMultipartUploadsInput(v *ListMultipar encoder.SetQuery("prefix").String(*v.Prefix) } + if len(v.RequestPayer) > 0 { + locationName := "X-Amz-Request-Payer" + encoder.SetHeader(locationName).String(string(v.RequestPayer)) + } + if v.UploadIdMarker != nil { encoder.SetQuery("upload-id-marker").String(*v.UploadIdMarker) } @@ -4686,11 +4587,18 @@ func (m *awsRestxml_serializeOpListObjects) HandleSerialize(ctx context.Context, return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}") + opPath, opQuery := httpbinding.SplitURI("/") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -4711,15 +4619,6 @@ func awsRestxml_serializeOpHttpBindingsListObjectsInput(v *ListObjectsInput, enc return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.Delimiter != nil { encoder.SetQuery("delimiter").String(*v.Delimiter) } @@ -4741,6 +4640,20 @@ func awsRestxml_serializeOpHttpBindingsListObjectsInput(v *ListObjectsInput, enc encoder.SetQuery("max-keys").Integer(v.MaxKeys) } + if v.OptionalObjectAttributes != nil { + locationName := "X-Amz-Optional-Object-Attributes" + for i := range v.OptionalObjectAttributes { + if len(v.OptionalObjectAttributes[i]) > 0 { + escaped := string(v.OptionalObjectAttributes[i]) + if strings.Index(string(v.OptionalObjectAttributes[i]), `,`) != -1 || strings.Index(string(v.OptionalObjectAttributes[i]), `"`) != -1 { + escaped = strconv.Quote(string(v.OptionalObjectAttributes[i])) + } + + encoder.AddHeader(locationName).String(string(escaped)) + } + } + } + if v.Prefix != nil { encoder.SetQuery("prefix").String(*v.Prefix) } @@ -4774,11 +4687,18 @@ func (m *awsRestxml_serializeOpListObjectsV2) HandleSerialize(ctx context.Contex return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?list-type=2") + opPath, opQuery := httpbinding.SplitURI("/?list-type=2") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -4799,15 +4719,6 @@ func awsRestxml_serializeOpHttpBindingsListObjectsV2Input(v *ListObjectsV2Input, return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ContinuationToken != nil { encoder.SetQuery("continuation-token").String(*v.ContinuationToken) } @@ -4833,6 +4744,20 @@ func awsRestxml_serializeOpHttpBindingsListObjectsV2Input(v *ListObjectsV2Input, encoder.SetQuery("max-keys").Integer(v.MaxKeys) } + if v.OptionalObjectAttributes != nil { + locationName := "X-Amz-Optional-Object-Attributes" + for i := range v.OptionalObjectAttributes { + if len(v.OptionalObjectAttributes[i]) > 0 { + escaped := string(v.OptionalObjectAttributes[i]) + if strings.Index(string(v.OptionalObjectAttributes[i]), `,`) != -1 || strings.Index(string(v.OptionalObjectAttributes[i]), `"`) != -1 { + escaped = strconv.Quote(string(v.OptionalObjectAttributes[i])) + } + + encoder.AddHeader(locationName).String(string(escaped)) + } + } + } + if v.Prefix != nil { encoder.SetQuery("prefix").String(*v.Prefix) } @@ -4870,11 +4795,18 @@ func (m *awsRestxml_serializeOpListObjectVersions) HandleSerialize(ctx context.C return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?versions") + opPath, opQuery := httpbinding.SplitURI("/?versions") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -4891,17 +4823,8 @@ func (m *awsRestxml_serializeOpListObjectVersions) HandleSerialize(ctx context.C return next.HandleSerialize(ctx, in) } func awsRestxml_serializeOpHttpBindingsListObjectVersionsInput(v *ListObjectVersionsInput, encoder *httpbinding.Encoder) error { - if v == nil { - return fmt.Errorf("unsupported serialization of nil %T", v) - } - - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } + if v == nil { + return fmt.Errorf("unsupported serialization of nil %T", v) } if v.Delimiter != nil { @@ -4925,10 +4848,29 @@ func awsRestxml_serializeOpHttpBindingsListObjectVersionsInput(v *ListObjectVers encoder.SetQuery("max-keys").Integer(v.MaxKeys) } + if v.OptionalObjectAttributes != nil { + locationName := "X-Amz-Optional-Object-Attributes" + for i := range v.OptionalObjectAttributes { + if len(v.OptionalObjectAttributes[i]) > 0 { + escaped := string(v.OptionalObjectAttributes[i]) + if strings.Index(string(v.OptionalObjectAttributes[i]), `,`) != -1 || strings.Index(string(v.OptionalObjectAttributes[i]), `"`) != -1 { + escaped = strconv.Quote(string(v.OptionalObjectAttributes[i])) + } + + encoder.AddHeader(locationName).String(string(escaped)) + } + } + } + if v.Prefix != nil { encoder.SetQuery("prefix").String(*v.Prefix) } + if len(v.RequestPayer) > 0 { + locationName := "X-Amz-Request-Payer" + encoder.SetHeader(locationName).String(string(v.RequestPayer)) + } + if v.VersionIdMarker != nil { encoder.SetQuery("version-id-marker").String(*v.VersionIdMarker) } @@ -4957,11 +4899,18 @@ func (m *awsRestxml_serializeOpListParts) HandleSerialize(ctx context.Context, i return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?x-id=ListParts") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?x-id=ListParts") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -4982,15 +4931,6 @@ func awsRestxml_serializeOpHttpBindingsListPartsInput(v *ListPartsInput, encoder return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -5061,11 +5001,18 @@ func (m *awsRestxml_serializeOpPutBucketAccelerateConfiguration) HandleSerialize return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?accelerate") + opPath, opQuery := httpbinding.SplitURI("/?accelerate") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -5110,15 +5057,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketAccelerateConfigurationInput(v * return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -5153,11 +5091,18 @@ func (m *awsRestxml_serializeOpPutBucketAcl) HandleSerialize(ctx context.Context return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?acl") + opPath, opQuery := httpbinding.SplitURI("/?acl") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -5207,15 +5152,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketAclInput(v *PutBucketAclInput, e encoder.SetHeader(locationName).String(string(v.ACL)) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -5280,11 +5216,18 @@ func (m *awsRestxml_serializeOpPutBucketAnalyticsConfiguration) HandleSerialize( return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?analytics") + opPath, opQuery := httpbinding.SplitURI("/?analytics") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -5329,15 +5272,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketAnalyticsConfigurationInput(v *P return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -5371,11 +5305,18 @@ func (m *awsRestxml_serializeOpPutBucketCors) HandleSerialize(ctx context.Contex return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?cors") + opPath, opQuery := httpbinding.SplitURI("/?cors") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -5420,15 +5361,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketCorsInput(v *PutBucketCorsInput, return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -5468,11 +5400,18 @@ func (m *awsRestxml_serializeOpPutBucketEncryption) HandleSerialize(ctx context. return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?encryption") + opPath, opQuery := httpbinding.SplitURI("/?encryption") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -5517,15 +5456,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketEncryptionInput(v *PutBucketEncr return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -5565,11 +5495,18 @@ func (m *awsRestxml_serializeOpPutBucketIntelligentTieringConfiguration) HandleS return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?intelligent-tiering") + opPath, opQuery := httpbinding.SplitURI("/?intelligent-tiering") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -5614,15 +5551,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketIntelligentTieringConfigurationI return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.Id != nil { encoder.SetQuery("id").String(*v.Id) } @@ -5651,11 +5579,18 @@ func (m *awsRestxml_serializeOpPutBucketInventoryConfiguration) HandleSerialize( return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?inventory") + opPath, opQuery := httpbinding.SplitURI("/?inventory") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -5700,15 +5635,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketInventoryConfigurationInput(v *P return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -5742,11 +5668,18 @@ func (m *awsRestxml_serializeOpPutBucketLifecycleConfiguration) HandleSerialize( return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?lifecycle") + opPath, opQuery := httpbinding.SplitURI("/?lifecycle") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -5791,15 +5724,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketLifecycleConfigurationInput(v *P return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -5834,11 +5758,18 @@ func (m *awsRestxml_serializeOpPutBucketLogging) HandleSerialize(ctx context.Con return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?logging") + opPath, opQuery := httpbinding.SplitURI("/?logging") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -5883,15 +5814,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketLoggingInput(v *PutBucketLogging return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -5931,11 +5853,18 @@ func (m *awsRestxml_serializeOpPutBucketMetricsConfiguration) HandleSerialize(ct return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?metrics") + opPath, opQuery := httpbinding.SplitURI("/?metrics") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -5980,15 +5909,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketMetricsConfigurationInput(v *Put return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -6022,11 +5942,18 @@ func (m *awsRestxml_serializeOpPutBucketNotificationConfiguration) HandleSeriali return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?notification") + opPath, opQuery := httpbinding.SplitURI("/?notification") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -6071,15 +5998,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketNotificationConfigurationInput(v return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -6114,11 +6032,18 @@ func (m *awsRestxml_serializeOpPutBucketOwnershipControls) HandleSerialize(ctx c return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?ownershipControls") + opPath, opQuery := httpbinding.SplitURI("/?ownershipControls") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -6163,15 +6088,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketOwnershipControlsInput(v *PutBuc return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ContentMD5 != nil && len(*v.ContentMD5) > 0 { locationName := "Content-Md5" encoder.SetHeader(locationName).String(*v.ContentMD5) @@ -6206,11 +6122,18 @@ func (m *awsRestxml_serializeOpPutBucketPolicy) HandleSerialize(ctx context.Cont return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?policy") + opPath, opQuery := httpbinding.SplitURI("/?policy") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -6243,15 +6166,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketPolicyInput(v *PutBucketPolicyIn return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -6296,11 +6210,18 @@ func (m *awsRestxml_serializeOpPutBucketReplication) HandleSerialize(ctx context return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?replication") + opPath, opQuery := httpbinding.SplitURI("/?replication") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -6345,15 +6266,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketReplicationInput(v *PutBucketRep return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -6398,11 +6310,18 @@ func (m *awsRestxml_serializeOpPutBucketRequestPayment) HandleSerialize(ctx cont return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?requestPayment") + opPath, opQuery := httpbinding.SplitURI("/?requestPayment") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -6447,15 +6366,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketRequestPaymentInput(v *PutBucket return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -6495,11 +6405,18 @@ func (m *awsRestxml_serializeOpPutBucketTagging) HandleSerialize(ctx context.Con return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?tagging") + opPath, opQuery := httpbinding.SplitURI("/?tagging") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -6544,15 +6461,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketTaggingInput(v *PutBucketTagging return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -6592,11 +6500,18 @@ func (m *awsRestxml_serializeOpPutBucketVersioning) HandleSerialize(ctx context. return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?versioning") + opPath, opQuery := httpbinding.SplitURI("/?versioning") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -6641,15 +6556,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketVersioningInput(v *PutBucketVers return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -6694,11 +6600,18 @@ func (m *awsRestxml_serializeOpPutBucketWebsite) HandleSerialize(ctx context.Con return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?website") + opPath, opQuery := httpbinding.SplitURI("/?website") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -6743,15 +6656,6 @@ func awsRestxml_serializeOpHttpBindingsPutBucketWebsiteInput(v *PutBucketWebsite return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -6791,11 +6695,18 @@ func (m *awsRestxml_serializeOpPutObject) HandleSerialize(ctx context.Context, i return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?x-id=PutObject") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?x-id=PutObject") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -6833,15 +6744,6 @@ func awsRestxml_serializeOpHttpBindingsPutObjectInput(v *PutObjectInput, encoder encoder.SetHeader(locationName).String(string(v.ACL)) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.BucketKeyEnabled { locationName := "X-Amz-Server-Side-Encryption-Bucket-Key-Enabled" encoder.SetHeader(locationName).Boolean(v.BucketKeyEnabled) @@ -7044,11 +6946,18 @@ func (m *awsRestxml_serializeOpPutObjectAcl) HandleSerialize(ctx context.Context return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?acl") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?acl") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -7098,15 +7007,6 @@ func awsRestxml_serializeOpHttpBindingsPutObjectAclInput(v *PutObjectAclInput, e encoder.SetHeader(locationName).String(string(v.ACL)) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -7189,11 +7089,18 @@ func (m *awsRestxml_serializeOpPutObjectLegalHold) HandleSerialize(ctx context.C return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?legal-hold") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?legal-hold") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -7238,15 +7145,6 @@ func awsRestxml_serializeOpHttpBindingsPutObjectLegalHoldInput(v *PutObjectLegal return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -7304,11 +7202,18 @@ func (m *awsRestxml_serializeOpPutObjectLockConfiguration) HandleSerialize(ctx c return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?object-lock") + opPath, opQuery := httpbinding.SplitURI("/?object-lock") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -7353,15 +7258,6 @@ func awsRestxml_serializeOpHttpBindingsPutObjectLockConfigurationInput(v *PutObj return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -7411,11 +7307,18 @@ func (m *awsRestxml_serializeOpPutObjectRetention) HandleSerialize(ctx context.C return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?retention") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?retention") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -7460,15 +7363,6 @@ func awsRestxml_serializeOpHttpBindingsPutObjectRetentionInput(v *PutObjectReten return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.BypassGovernanceRetention { locationName := "X-Amz-Bypass-Governance-Retention" encoder.SetHeader(locationName).Boolean(v.BypassGovernanceRetention) @@ -7531,11 +7425,18 @@ func (m *awsRestxml_serializeOpPutObjectTagging) HandleSerialize(ctx context.Con return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?tagging") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?tagging") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -7580,15 +7481,6 @@ func awsRestxml_serializeOpHttpBindingsPutObjectTaggingInput(v *PutObjectTagging return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -7646,11 +7538,18 @@ func (m *awsRestxml_serializeOpPutPublicAccessBlock) HandleSerialize(ctx context return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}?publicAccessBlock") + opPath, opQuery := httpbinding.SplitURI("/?publicAccessBlock") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -7695,15 +7594,6 @@ func awsRestxml_serializeOpHttpBindingsPutPublicAccessBlockInput(v *PutPublicAcc return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -7743,11 +7633,18 @@ func (m *awsRestxml_serializeOpRestoreObject) HandleSerialize(ctx context.Contex return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?restore&x-id=RestoreObject") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?restore&x-id=RestoreObject") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "POST" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -7792,15 +7689,6 @@ func awsRestxml_serializeOpHttpBindingsRestoreObjectInput(v *RestoreObjectInput, return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -7853,11 +7741,18 @@ func (m *awsRestxml_serializeOpSelectObjectContent) HandleSerialize(ctx context. return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?select&select-type=2&x-id=SelectObjectContent") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?select&select-type=2&x-id=SelectObjectContent") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "POST" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -7896,15 +7791,6 @@ func awsRestxml_serializeOpHttpBindingsSelectObjectContentInput(v *SelectObjectC return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.ExpectedBucketOwner != nil && len(*v.ExpectedBucketOwner) > 0 { locationName := "X-Amz-Expected-Bucket-Owner" encoder.SetHeader(locationName).String(*v.ExpectedBucketOwner) @@ -8037,11 +7923,18 @@ func (m *awsRestxml_serializeOpUploadPart) HandleSerialize(ctx context.Context, return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?x-id=UploadPart") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?x-id=UploadPart") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -8074,15 +7967,6 @@ func awsRestxml_serializeOpHttpBindingsUploadPartInput(v *UploadPartInput, encod return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if len(v.ChecksumAlgorithm) > 0 { locationName := "X-Amz-Sdk-Checksum-Algorithm" encoder.SetHeader(locationName).String(string(v.ChecksumAlgorithm)) @@ -8184,11 +8068,18 @@ func (m *awsRestxml_serializeOpUploadPartCopy) HandleSerialize(ctx context.Conte return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} } - opPath, opQuery := httpbinding.SplitURI("/{Bucket}/{Key+}?x-id=UploadPartCopy") + opPath, opQuery := httpbinding.SplitURI("/{Key+}?x-id=UploadPartCopy") request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "PUT" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -8209,15 +8100,6 @@ func awsRestxml_serializeOpHttpBindingsUploadPartCopyInput(v *UploadPartCopyInpu return fmt.Errorf("unsupported serialization of nil %T", v) } - if v.Bucket == nil || len(*v.Bucket) == 0 { - return &smithy.SerializationError{Err: fmt.Errorf("input member Bucket must not be empty")} - } - if v.Bucket != nil { - if err := encoder.SetURI("Bucket").String(*v.Bucket); err != nil { - return err - } - } - if v.CopySource != nil && len(*v.CopySource) > 0 { locationName := "X-Amz-Copy-Source" encoder.SetHeader(locationName).String(*v.CopySource) @@ -8338,7 +8220,14 @@ func (m *awsRestxml_serializeOpWriteGetObjectResponse) HandleSerialize(ctx conte request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "POST" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/types/enums.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/types/enums.go index 5b5254083..613da169d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/types/enums.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/types/enums.go @@ -88,6 +88,7 @@ const ( BucketLocationConstraintApSouth1 BucketLocationConstraint = "ap-south-1" BucketLocationConstraintApSoutheast1 BucketLocationConstraint = "ap-southeast-1" BucketLocationConstraintApSoutheast2 BucketLocationConstraint = "ap-southeast-2" + BucketLocationConstraintApSoutheast3 BucketLocationConstraint = "ap-southeast-3" BucketLocationConstraintCaCentral1 BucketLocationConstraint = "ca-central-1" BucketLocationConstraintCnNorth1 BucketLocationConstraint = "cn-north-1" BucketLocationConstraintCnNorthwest1 BucketLocationConstraint = "cn-northwest-1" @@ -105,11 +106,13 @@ const ( BucketLocationConstraintUsGovWest1 BucketLocationConstraint = "us-gov-west-1" BucketLocationConstraintUsWest1 BucketLocationConstraint = "us-west-1" BucketLocationConstraintUsWest2 BucketLocationConstraint = "us-west-2" + BucketLocationConstraintApSouth2 BucketLocationConstraint = "ap-south-2" + BucketLocationConstraintEuSouth2 BucketLocationConstraint = "eu-south-2" ) -// Values returns all known values for BucketLocationConstraint. Note that this can -// be expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. +// Values returns all known values for BucketLocationConstraint. Note that this +// can be expanded in the future, and so it is only as up to date as the client. +// The ordering of this slice is not guaranteed to be stable across updates. func (BucketLocationConstraint) Values() []BucketLocationConstraint { return []BucketLocationConstraint{ "af-south-1", @@ -120,6 +123,7 @@ func (BucketLocationConstraint) Values() []BucketLocationConstraint { "ap-south-1", "ap-southeast-1", "ap-southeast-2", + "ap-southeast-3", "ca-central-1", "cn-north-1", "cn-northwest-1", @@ -137,6 +141,8 @@ func (BucketLocationConstraint) Values() []BucketLocationConstraint { "us-gov-west-1", "us-west-1", "us-west-2", + "ap-south-2", + "eu-south-2", } } @@ -207,9 +213,9 @@ const ( ChecksumModeEnabled ChecksumMode = "ENABLED" ) -// Values returns all known values for ChecksumMode. Note that this can be expanded -// in the future, and so it is only as up to date as the client. The ordering of -// this slice is not guaranteed to be stable across updates. +// Values returns all known values for ChecksumMode. Note that this can be +// expanded in the future, and so it is only as up to date as the client. The +// ordering of this slice is not guaranteed to be stable across updates. func (ChecksumMode) Values() []ChecksumMode { return []ChecksumMode{ "ENABLED", @@ -262,9 +268,9 @@ const ( EncodingTypeUrl EncodingType = "url" ) -// Values returns all known values for EncodingType. Note that this can be expanded -// in the future, and so it is only as up to date as the client. The ordering of -// this slice is not guaranteed to be stable across updates. +// Values returns all known values for EncodingType. Note that this can be +// expanded in the future, and so it is only as up to date as the client. The +// ordering of this slice is not guaranteed to be stable across updates. func (EncodingType) Values() []EncodingType { return []EncodingType{ "url", @@ -273,8 +279,39 @@ func (EncodingType) Values() []EncodingType { type Event string -// Values returns all known values for Event. Note that this can be expanded in the -// future, and so it is only as up to date as the client. The ordering of this +// Enum values for Event +const ( + EventS3ReducedRedundancyLostObject Event = "s3:ReducedRedundancyLostObject" + EventS3ObjectCreated Event = "s3:ObjectCreated:*" + EventS3ObjectCreatedPut Event = "s3:ObjectCreated:Put" + EventS3ObjectCreatedPost Event = "s3:ObjectCreated:Post" + EventS3ObjectCreatedCopy Event = "s3:ObjectCreated:Copy" + EventS3ObjectCreatedCompleteMultipartUpload Event = "s3:ObjectCreated:CompleteMultipartUpload" + EventS3ObjectRemoved Event = "s3:ObjectRemoved:*" + EventS3ObjectRemovedDelete Event = "s3:ObjectRemoved:Delete" + EventS3ObjectRemovedDeleteMarkerCreated Event = "s3:ObjectRemoved:DeleteMarkerCreated" + EventS3ObjectRestore Event = "s3:ObjectRestore:*" + EventS3ObjectRestorePost Event = "s3:ObjectRestore:Post" + EventS3ObjectRestoreCompleted Event = "s3:ObjectRestore:Completed" + EventS3Replication Event = "s3:Replication:*" + EventS3ReplicationOperationFailedReplication Event = "s3:Replication:OperationFailedReplication" + EventS3ReplicationOperationNotTracked Event = "s3:Replication:OperationNotTracked" + EventS3ReplicationOperationMissedThreshold Event = "s3:Replication:OperationMissedThreshold" + EventS3ReplicationOperationReplicatedAfterThreshold Event = "s3:Replication:OperationReplicatedAfterThreshold" + EventS3ObjectRestoreDelete Event = "s3:ObjectRestore:Delete" + EventS3LifecycleTransition Event = "s3:LifecycleTransition" + EventS3IntelligentTiering Event = "s3:IntelligentTiering" + EventS3ObjectAclPut Event = "s3:ObjectAcl:Put" + EventS3LifecycleExpiration Event = "s3:LifecycleExpiration:*" + EventS3LifecycleExpirationDelete Event = "s3:LifecycleExpiration:Delete" + EventS3LifecycleExpirationDeleteMarkerCreated Event = "s3:LifecycleExpiration:DeleteMarkerCreated" + EventS3ObjectTagging Event = "s3:ObjectTagging:*" + EventS3ObjectTaggingPut Event = "s3:ObjectTagging:Put" + EventS3ObjectTaggingDelete Event = "s3:ObjectTagging:Delete" +) + +// Values returns all known values for Event. Note that this can be expanded in +// the future, and so it is only as up to date as the client. The ordering of this // slice is not guaranteed to be stable across updates. func (Event) Values() []Event { return []Event{ @@ -407,9 +444,10 @@ const ( IntelligentTieringAccessTierDeepArchiveAccess IntelligentTieringAccessTier = "DEEP_ARCHIVE_ACCESS" ) -// Values returns all known values for IntelligentTieringAccessTier. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. +// Values returns all known values for IntelligentTieringAccessTier. Note that +// this can be expanded in the future, and so it is only as up to date as the +// client. The ordering of this slice is not guaranteed to be stable across +// updates. func (IntelligentTieringAccessTier) Values() []IntelligentTieringAccessTier { return []IntelligentTieringAccessTier{ "ARCHIVE_ACCESS", @@ -425,9 +463,9 @@ const ( IntelligentTieringStatusDisabled IntelligentTieringStatus = "Disabled" ) -// Values returns all known values for IntelligentTieringStatus. Note that this can -// be expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. +// Values returns all known values for IntelligentTieringStatus. Note that this +// can be expanded in the future, and so it is only as up to date as the client. +// The ordering of this slice is not guaranteed to be stable across updates. func (IntelligentTieringStatus) Values() []IntelligentTieringStatus { return []IntelligentTieringStatus{ "Enabled", @@ -509,6 +547,8 @@ const ( InventoryOptionalFieldIntelligentTieringAccessTier InventoryOptionalField = "IntelligentTieringAccessTier" InventoryOptionalFieldBucketKeyStatus InventoryOptionalField = "BucketKeyStatus" InventoryOptionalFieldChecksumAlgorithm InventoryOptionalField = "ChecksumAlgorithm" + InventoryOptionalFieldObjectAccessControlList InventoryOptionalField = "ObjectAccessControlList" + InventoryOptionalFieldObjectOwner InventoryOptionalField = "ObjectOwner" ) // Values returns all known values for InventoryOptionalField. Note that this can @@ -529,6 +569,8 @@ func (InventoryOptionalField) Values() []InventoryOptionalField { "IntelligentTieringAccessTier", "BucketKeyStatus", "ChecksumAlgorithm", + "ObjectAccessControlList", + "ObjectOwner", } } @@ -594,9 +636,9 @@ const ( MFADeleteDisabled MFADelete = "Disabled" ) -// Values returns all known values for MFADelete. Note that this can be expanded in -// the future, and so it is only as up to date as the client. The ordering of this -// slice is not guaranteed to be stable across updates. +// Values returns all known values for MFADelete. Note that this can be expanded +// in the future, and so it is only as up to date as the client. The ordering of +// this slice is not guaranteed to be stable across updates. func (MFADelete) Values() []MFADelete { return []MFADelete{ "Enabled", @@ -777,6 +819,7 @@ const ( ObjectStorageClassDeepArchive ObjectStorageClass = "DEEP_ARCHIVE" ObjectStorageClassOutposts ObjectStorageClass = "OUTPOSTS" ObjectStorageClassGlacierIr ObjectStorageClass = "GLACIER_IR" + ObjectStorageClassSnow ObjectStorageClass = "SNOW" ) // Values returns all known values for ObjectStorageClass. Note that this can be @@ -793,6 +836,7 @@ func (ObjectStorageClass) Values() []ObjectStorageClass { "DEEP_ARCHIVE", "OUTPOSTS", "GLACIER_IR", + "SNOW", } } @@ -812,6 +856,22 @@ func (ObjectVersionStorageClass) Values() []ObjectVersionStorageClass { } } +type OptionalObjectAttributes string + +// Enum values for OptionalObjectAttributes +const ( + OptionalObjectAttributesRestoreStatus OptionalObjectAttributes = "RestoreStatus" +) + +// Values returns all known values for OptionalObjectAttributes. Note that this +// can be expanded in the future, and so it is only as up to date as the client. +// The ordering of this slice is not guaranteed to be stable across updates. +func (OptionalObjectAttributes) Values() []OptionalObjectAttributes { + return []OptionalObjectAttributes{ + "RestoreStatus", + } +} + type OwnerOverride string // Enum values for OwnerOverride @@ -836,8 +896,8 @@ const ( PayerBucketOwner Payer = "BucketOwner" ) -// Values returns all known values for Payer. Note that this can be expanded in the -// future, and so it is only as up to date as the client. The ordering of this +// Values returns all known values for Payer. Note that this can be expanded in +// the future, and so it is only as up to date as the client. The ordering of this // slice is not guaranteed to be stable across updates. func (Payer) Values() []Payer { return []Payer{ @@ -932,8 +992,8 @@ const ( ReplicationRuleStatusDisabled ReplicationRuleStatus = "Disabled" ) -// Values returns all known values for ReplicationRuleStatus. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The +// Values returns all known values for ReplicationRuleStatus. Note that this can +// be expanded in the future, and so it is only as up to date as the client. The // ordering of this slice is not guaranteed to be stable across updates. func (ReplicationRuleStatus) Values() []ReplicationRuleStatus { return []ReplicationRuleStatus{ @@ -946,10 +1006,11 @@ type ReplicationStatus string // Enum values for ReplicationStatus const ( - ReplicationStatusComplete ReplicationStatus = "COMPLETE" - ReplicationStatusPending ReplicationStatus = "PENDING" - ReplicationStatusFailed ReplicationStatus = "FAILED" - ReplicationStatusReplica ReplicationStatus = "REPLICA" + ReplicationStatusComplete ReplicationStatus = "COMPLETE" + ReplicationStatusPending ReplicationStatus = "PENDING" + ReplicationStatusFailed ReplicationStatus = "FAILED" + ReplicationStatusReplica ReplicationStatus = "REPLICA" + ReplicationStatusCompleted ReplicationStatus = "COMPLETED" ) // Values returns all known values for ReplicationStatus. Note that this can be @@ -961,6 +1022,7 @@ func (ReplicationStatus) Values() []ReplicationStatus { "PENDING", "FAILED", "REPLICA", + "COMPLETED", } } @@ -972,8 +1034,8 @@ const ( ReplicationTimeStatusDisabled ReplicationTimeStatus = "Disabled" ) -// Values returns all known values for ReplicationTimeStatus. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The +// Values returns all known values for ReplicationTimeStatus. Note that this can +// be expanded in the future, and so it is only as up to date as the client. The // ordering of this slice is not guaranteed to be stable across updates. func (ReplicationTimeStatus) Values() []ReplicationTimeStatus { return []ReplicationTimeStatus{ @@ -1005,9 +1067,9 @@ const ( RequestPayerRequester RequestPayer = "requester" ) -// Values returns all known values for RequestPayer. Note that this can be expanded -// in the future, and so it is only as up to date as the client. The ordering of -// this slice is not guaranteed to be stable across updates. +// Values returns all known values for RequestPayer. Note that this can be +// expanded in the future, and so it is only as up to date as the client. The +// ordering of this slice is not guaranteed to be stable across updates. func (RequestPayer) Values() []RequestPayer { return []RequestPayer{ "requester", @@ -1034,8 +1096,9 @@ type ServerSideEncryption string // Enum values for ServerSideEncryption const ( - ServerSideEncryptionAes256 ServerSideEncryption = "AES256" - ServerSideEncryptionAwsKms ServerSideEncryption = "aws:kms" + ServerSideEncryptionAes256 ServerSideEncryption = "AES256" + ServerSideEncryptionAwsKms ServerSideEncryption = "aws:kms" + ServerSideEncryptionAwsKmsDsse ServerSideEncryption = "aws:kms:dsse" ) // Values returns all known values for ServerSideEncryption. Note that this can be @@ -1045,6 +1108,7 @@ func (ServerSideEncryption) Values() []ServerSideEncryption { return []ServerSideEncryption{ "AES256", "aws:kms", + "aws:kms:dsse", } } @@ -1056,9 +1120,10 @@ const ( SseKmsEncryptedObjectsStatusDisabled SseKmsEncryptedObjectsStatus = "Disabled" ) -// Values returns all known values for SseKmsEncryptedObjectsStatus. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. +// Values returns all known values for SseKmsEncryptedObjectsStatus. Note that +// this can be expanded in the future, and so it is only as up to date as the +// client. The ordering of this slice is not guaranteed to be stable across +// updates. func (SseKmsEncryptedObjectsStatus) Values() []SseKmsEncryptedObjectsStatus { return []SseKmsEncryptedObjectsStatus{ "Enabled", @@ -1079,11 +1144,12 @@ const ( StorageClassDeepArchive StorageClass = "DEEP_ARCHIVE" StorageClassOutposts StorageClass = "OUTPOSTS" StorageClassGlacierIr StorageClass = "GLACIER_IR" + StorageClassSnow StorageClass = "SNOW" ) -// Values returns all known values for StorageClass. Note that this can be expanded -// in the future, and so it is only as up to date as the client. The ordering of -// this slice is not guaranteed to be stable across updates. +// Values returns all known values for StorageClass. Note that this can be +// expanded in the future, and so it is only as up to date as the client. The +// ordering of this slice is not guaranteed to be stable across updates. func (StorageClass) Values() []StorageClass { return []StorageClass{ "STANDARD", @@ -1095,6 +1161,7 @@ func (StorageClass) Values() []StorageClass { "DEEP_ARCHIVE", "OUTPOSTS", "GLACIER_IR", + "SNOW", } } @@ -1105,8 +1172,8 @@ const ( StorageClassAnalysisSchemaVersionV1 StorageClassAnalysisSchemaVersion = "V_1" ) -// Values returns all known values for StorageClassAnalysisSchemaVersion. Note that -// this can be expanded in the future, and so it is only as up to date as the +// Values returns all known values for StorageClassAnalysisSchemaVersion. Note +// that this can be expanded in the future, and so it is only as up to date as the // client. The ordering of this slice is not guaranteed to be stable across // updates. func (StorageClassAnalysisSchemaVersion) Values() []StorageClassAnalysisSchemaVersion { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/types/errors.go index 8c3a386f7..f3837866d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/types/errors.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/types/errors.go @@ -12,6 +12,8 @@ import ( type BucketAlreadyExists struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -24,17 +26,24 @@ func (e *BucketAlreadyExists) ErrorMessage() string { } return *e.Message } -func (e *BucketAlreadyExists) ErrorCode() string { return "BucketAlreadyExists" } +func (e *BucketAlreadyExists) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "BucketAlreadyExists" + } + return *e.ErrorCodeOverride +} func (e *BucketAlreadyExists) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } -// The bucket you tried to create already exists, and you own it. Amazon S3 returns -// this error in all Amazon Web Services Regions except in the North Virginia -// Region. For legacy compatibility, if you re-create an existing bucket that you -// already own in the North Virginia Region, Amazon S3 returns 200 OK and resets -// the bucket access control lists (ACLs). +// The bucket you tried to create already exists, and you own it. Amazon S3 +// returns this error in all Amazon Web Services Regions except in the North +// Virginia Region. For legacy compatibility, if you re-create an existing bucket +// that you already own in the North Virginia Region, Amazon S3 returns 200 OK and +// resets the bucket access control lists (ACLs). type BucketAlreadyOwnedByYou struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -47,13 +56,20 @@ func (e *BucketAlreadyOwnedByYou) ErrorMessage() string { } return *e.Message } -func (e *BucketAlreadyOwnedByYou) ErrorCode() string { return "BucketAlreadyOwnedByYou" } +func (e *BucketAlreadyOwnedByYou) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "BucketAlreadyOwnedByYou" + } + return *e.ErrorCodeOverride +} func (e *BucketAlreadyOwnedByYou) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } // Object is archived and inaccessible until restored. type InvalidObjectState struct { Message *string + ErrorCodeOverride *string + StorageClass StorageClass AccessTier IntelligentTieringAccessTier @@ -69,13 +85,20 @@ func (e *InvalidObjectState) ErrorMessage() string { } return *e.Message } -func (e *InvalidObjectState) ErrorCode() string { return "InvalidObjectState" } +func (e *InvalidObjectState) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "InvalidObjectState" + } + return *e.ErrorCodeOverride +} func (e *InvalidObjectState) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } // The specified bucket does not exist. type NoSuchBucket struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -88,13 +111,20 @@ func (e *NoSuchBucket) ErrorMessage() string { } return *e.Message } -func (e *NoSuchBucket) ErrorCode() string { return "NoSuchBucket" } +func (e *NoSuchBucket) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "NoSuchBucket" + } + return *e.ErrorCodeOverride +} func (e *NoSuchBucket) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } // The specified key does not exist. type NoSuchKey struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -107,13 +137,20 @@ func (e *NoSuchKey) ErrorMessage() string { } return *e.Message } -func (e *NoSuchKey) ErrorCode() string { return "NoSuchKey" } +func (e *NoSuchKey) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "NoSuchKey" + } + return *e.ErrorCodeOverride +} func (e *NoSuchKey) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } // The specified multipart upload does not exist. type NoSuchUpload struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -126,13 +163,20 @@ func (e *NoSuchUpload) ErrorMessage() string { } return *e.Message } -func (e *NoSuchUpload) ErrorCode() string { return "NoSuchUpload" } +func (e *NoSuchUpload) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "NoSuchUpload" + } + return *e.ErrorCodeOverride +} func (e *NoSuchUpload) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } // The specified content does not exist. type NotFound struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -145,13 +189,20 @@ func (e *NotFound) ErrorMessage() string { } return *e.Message } -func (e *NotFound) ErrorCode() string { return "NotFound" } +func (e *NotFound) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "NotFound" + } + return *e.ErrorCodeOverride +} func (e *NotFound) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } // This action is not allowed against this storage tier. type ObjectAlreadyInActiveTierError struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -164,7 +215,12 @@ func (e *ObjectAlreadyInActiveTierError) ErrorMessage() string { } return *e.Message } -func (e *ObjectAlreadyInActiveTierError) ErrorCode() string { return "ObjectAlreadyInActiveTierError" } +func (e *ObjectAlreadyInActiveTierError) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "ObjectAlreadyInActiveTierError" + } + return *e.ErrorCodeOverride +} func (e *ObjectAlreadyInActiveTierError) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } // The source object of the COPY action is not in the active tier and is only @@ -172,6 +228,8 @@ func (e *ObjectAlreadyInActiveTierError) ErrorFault() smithy.ErrorFault { return type ObjectNotInActiveTierError struct { Message *string + ErrorCodeOverride *string + noSmithyDocumentSerde } @@ -184,5 +242,10 @@ func (e *ObjectNotInActiveTierError) ErrorMessage() string { } return *e.Message } -func (e *ObjectNotInActiveTierError) ErrorCode() string { return "ObjectNotInActiveTierError" } +func (e *ObjectNotInActiveTierError) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "ObjectNotInActiveTierError" + } + return *e.ErrorCodeOverride +} func (e *ObjectNotInActiveTierError) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/types/types.go b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/types/types.go index bcef62cec..3ddea0a24 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/s3/types/types.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/s3/types/types.go @@ -9,9 +9,8 @@ import ( // Specifies the days since the initiation of an incomplete multipart upload that // Amazon S3 will wait before permanently removing all parts of the upload. For -// more information, see Aborting Incomplete Multipart Uploads Using a Bucket -// Lifecycle Policy -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config) +// more information, see Aborting Incomplete Multipart Uploads Using a Bucket +// Lifecycle Configuration (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config) // in the Amazon S3 User Guide. type AbortIncompleteMultipartUpload struct { @@ -23,9 +22,8 @@ type AbortIncompleteMultipartUpload struct { } // Configures the transfer acceleration state for an Amazon S3 bucket. For more -// information, see Amazon S3 Transfer Acceleration -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html) in -// the Amazon S3 User Guide. +// information, see Amazon S3 Transfer Acceleration (https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html) +// in the Amazon S3 User Guide. type AccelerateConfiguration struct { // Specifies the transfer acceleration status of the bucket. @@ -50,8 +48,7 @@ type AccessControlPolicy struct { type AccessControlTranslation struct { // Specifies the replica ownership. For default and valid values, see PUT bucket - // replication - // (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTreplication.html) + // replication (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTreplication.html) // in the Amazon S3 API Reference. // // This member is required. @@ -60,9 +57,10 @@ type AccessControlTranslation struct { noSmithyDocumentSerde } -// A conjunction (logical AND) of predicates, which is used in evaluating a metrics -// filter. The operator must have at least two predicates in any combination, and -// an object must match all of the predicates for the filter to apply. +// A conjunction (logical AND) of predicates, which is used in evaluating a +// metrics filter. The operator must have at least two predicates in any +// combination, and an object must match all of the predicates for the filter to +// apply. type AnalyticsAndOperator struct { // The prefix to use when evaluating an AND predicate: The prefix that an object @@ -191,9 +189,8 @@ type Bucket struct { } // Specifies the lifecycle configuration for objects in an Amazon S3 bucket. For -// more information, see Object Lifecycle Management -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html) in -// the Amazon S3 User Guide. +// more information, see Object Lifecycle Management (https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html) +// in the Amazon S3 User Guide. type BucketLifecycleConfiguration struct { // A lifecycle rule for individual objects in an Amazon S3 bucket. @@ -207,10 +204,9 @@ type BucketLifecycleConfiguration struct { // Container for logging status information. type BucketLoggingStatus struct { - // Describes where logs are stored and the prefix that Amazon S3 assigns to all log - // object keys for a bucket. For more information, see PUT Bucket logging - // (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlogging.html) in - // the Amazon S3 API Reference. + // Describes where logs are stored and the prefix that Amazon S3 assigns to all + // log object keys for a bucket. For more information, see PUT Bucket logging (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlogging.html) + // in the Amazon S3 API Reference. LoggingEnabled *LoggingEnabled noSmithyDocumentSerde @@ -222,43 +218,39 @@ type Checksum struct { // The base64-encoded, 32-bit CRC32 checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32 *string // The base64-encoded, 32-bit CRC32C checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32C *string // The base64-encoded, 160-bit SHA-1 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA1 *string // The base64-encoded, 256-bit SHA-256 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA256 *string noSmithyDocumentSerde } -// Container for all (if there are any) keys between Prefix and the next occurrence -// of the string specified by a delimiter. CommonPrefixes lists keys that act like -// subdirectories in the directory specified by Prefix. For example, if the prefix -// is notes/ and the delimiter is a slash (/) as in notes/summer/july, the common -// prefix is notes/summer/. +// Container for all (if there are any) keys between Prefix and the next +// occurrence of the string specified by a delimiter. CommonPrefixes lists keys +// that act like subdirectories in the directory specified by Prefix. For example, +// if the prefix is notes/ and the delimiter is a slash (/) as in +// notes/summer/july, the common prefix is notes/summer/. type CommonPrefix struct { // Container for the specified common prefix. @@ -283,32 +275,28 @@ type CompletedPart struct { // The base64-encoded, 32-bit CRC32 checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32 *string // The base64-encoded, 32-bit CRC32C checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32C *string // The base64-encoded, 160-bit SHA-1 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA1 *string // The base64-encoded, 256-bit SHA-256 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA256 *string @@ -336,15 +324,15 @@ type Condition struct { HttpErrorCodeReturnedEquals *string // The object key name prefix when the redirect is applied. For example, to - // redirect requests for ExamplePage.html, the key prefix will be ExamplePage.html. - // To redirect request for all pages with the prefix docs/, the key prefix will be - // /docs, which identifies all objects in the docs/ folder. Required when the - // parent element Condition is specified and sibling HttpErrorCodeReturnedEquals is - // not specified. If both conditions are specified, both must be true for the + // redirect requests for ExamplePage.html , the key prefix will be ExamplePage.html + // . To redirect request for all pages with the prefix docs/ , the key prefix will + // be /docs , which identifies all objects in the docs/ folder. Required when the + // parent element Condition is specified and sibling HttpErrorCodeReturnedEquals + // is not specified. If both conditions are specified, both must be true for the // redirect to be applied. Replacement must be made for object keys containing // special characters (such as carriage returns) when using XML requests. For more - // information, see XML related object key constraints - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints). + // information, see XML related object key constraints (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints) + // . KeyPrefixEquals *string noSmithyDocumentSerde @@ -360,32 +348,28 @@ type CopyObjectResult struct { // The base64-encoded, 32-bit CRC32 checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32 *string // The base64-encoded, 32-bit CRC32C checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32C *string // The base64-encoded, 160-bit SHA-1 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA1 *string // The base64-encoded, 256-bit SHA-256 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA256 *string @@ -405,32 +389,28 @@ type CopyPartResult struct { // The base64-encoded, 32-bit CRC32 checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32 *string // The base64-encoded, 32-bit CRC32C checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32C *string // The base64-encoded, 160-bit SHA-1 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA1 *string // The base64-encoded, 256-bit SHA-256 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA256 *string @@ -444,9 +424,8 @@ type CopyPartResult struct { } // Describes the cross-origin access configuration for objects in an Amazon S3 -// bucket. For more information, see Enabling Cross-Origin Resource Sharing -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html) in the Amazon S3 -// User Guide. +// bucket. For more information, see Enabling Cross-Origin Resource Sharing (https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html) +// in the Amazon S3 User Guide. type CORSConfiguration struct { // A set of origins and methods (cross-origin access that you want to allow). You @@ -461,8 +440,8 @@ type CORSConfiguration struct { // Specifies a cross-origin access rule for an Amazon S3 bucket. type CORSRule struct { - // An HTTP method that you allow the origin to execute. Valid values are GET, PUT, - // HEAD, POST, and DELETE. + // An HTTP method that you allow the origin to execute. Valid values are GET , PUT + // , HEAD , POST , and DELETE . // // This member is required. AllowedMethods []string @@ -477,15 +456,16 @@ type CORSRule struct { // OPTIONS request, Amazon S3 returns any requested headers that are allowed. AllowedHeaders []string - // One or more headers in the response that you want customers to be able to access - // from their applications (for example, from a JavaScript XMLHttpRequest object). + // One or more headers in the response that you want customers to be able to + // access from their applications (for example, from a JavaScript XMLHttpRequest + // object). ExposeHeaders []string // Unique identifier for the rule. The value cannot be longer than 255 characters. ID *string - // The time in seconds that your browser is to cache the preflight response for the - // specified resource. + // The time in seconds that your browser is to cache the preflight response for + // the specified resource. MaxAgeSeconds int32 noSmithyDocumentSerde @@ -512,7 +492,7 @@ type CSVInput struct { // A single character used to indicate that a row should be ignored when the // character is present at the start of that row. You can specify any character to - // indicate a comment line. + // indicate a comment line. The default character is # . Default: # Comments *string // A single character used to separate individual fields in a record. You can @@ -520,27 +500,22 @@ type CSVInput struct { FieldDelimiter *string // Describes the first line of input. Valid values are: - // - // * NONE: First line is not - // a header. - // - // * IGNORE: First line is a header, but you can't use the header values - // to indicate the column in an expression. You can use column position (such as - // _1, _2, …) to indicate the column (SELECT s._1 FROM OBJECT s). - // - // * Use: First - // line is a header, and you can use the header value to identify a column in an - // expression (SELECT "name" FROM OBJECT). + // - NONE : First line is not a header. + // - IGNORE : First line is a header, but you can't use the header values to + // indicate the column in an expression. You can use column position (such as _1, + // _2, …) to indicate the column ( SELECT s._1 FROM OBJECT s ). + // - Use : First line is a header, and you can use the header value to identify a + // column in an expression ( SELECT "name" FROM OBJECT ). FileHeaderInfo FileHeaderInfo // A single character used for escaping when the field delimiter is part of the - // value. For example, if the value is a, b, Amazon S3 wraps this field value in - // quotation marks, as follows: " a , b ". Type: String Default: " Ancestors: CSV + // value. For example, if the value is a, b , Amazon S3 wraps this field value in + // quotation marks, as follows: " a , b " . Type: String Default: " Ancestors: CSV QuoteCharacter *string // A single character used for escaping the quotation mark character inside an - // already escaped value. For example, the value """ a , b """ is parsed as " a , b - // ". + // already escaped value. For example, the value """ a , b """ is parsed as " a , + // b " . QuoteEscapeCharacter *string // A single character used to separate individual records in the input. Instead of @@ -559,8 +534,8 @@ type CSVOutput struct { FieldDelimiter *string // A single character used for escaping when the field delimiter is part of the - // value. For example, if the value is a, b, Amazon S3 wraps this field value in - // quotation marks, as follows: " a , b ". + // value. For example, if the value is a, b , Amazon S3 wraps this field value in + // quotation marks, as follows: " a , b " . QuoteCharacter *string // The single character used for escaping the quote character inside an already @@ -568,16 +543,12 @@ type CSVOutput struct { QuoteEscapeCharacter *string // Indicates whether to use quotation marks around output fields. - // - // * ALWAYS: Always - // use quotation marks for output fields. - // - // * ASNEEDED: Use quotation marks for - // output fields when needed. + // - ALWAYS : Always use quotation marks for output fields. + // - ASNEEDED : Use quotation marks for output fields when needed. QuoteFields QuoteFields - // A single character used to separate individual records in the output. Instead of - // the default value, you can specify an arbitrary delimiter. + // A single character used to separate individual records in the output. Instead + // of the default value, you can specify an arbitrary delimiter. RecordDelimiter *string noSmithyDocumentSerde @@ -585,25 +556,21 @@ type CSVOutput struct { // The container element for specifying the default Object Lock retention settings // for new objects placed in the specified bucket. -// -// * The DefaultRetention settings -// require both a mode and a period. -// -// * The DefaultRetention period can be either -// Days or Years but you must select one. You cannot specify Days and Years at the -// same time. +// - The DefaultRetention settings require both a mode and a period. +// - The DefaultRetention period can be either Days or Years but you must select +// one. You cannot specify Days and Years at the same time. type DefaultRetention struct { // The number of days that you want to specify for the default retention period. - // Must be used with Mode. + // Must be used with Mode . Days int32 // The default Object Lock retention mode you want to apply to new objects placed - // in the specified bucket. Must be used with either Days or Years. + // in the specified bucket. Must be used with either Days or Years . Mode ObjectLockRetentionMode // The number of years that you want to specify for the default retention period. - // Must be used with Mode. + // Must be used with Mode . Years int32 noSmithyDocumentSerde @@ -612,7 +579,7 @@ type DefaultRetention struct { // Container for the objects to delete. type Delete struct { - // The objects to delete. + // The object to delete. // // This member is required. Objects []ObjectIdentifier @@ -627,14 +594,15 @@ type Delete struct { // Information about the deleted object. type DeletedObject struct { - // Specifies whether the versioned object that was permanently deleted was (true) - // or was not (false) a delete marker. In a simple DELETE, this header indicates - // whether (true) or not (false) a delete marker was created. + // Indicates whether the specified object version that was permanently deleted was + // (true) or was not (false) a delete marker before deletion. In a simple DELETE, + // this header indicates whether (true) or not (false) the current version of the + // object is a delete marker. DeleteMarker bool - // The version ID of the delete marker created as a result of the DELETE operation. - // If you delete a specific object version, the value returned by this header is - // the version ID of the object version deleted. + // The version ID of the delete marker created as a result of the DELETE + // operation. If you delete a specific object version, the value returned by this + // header is the version ID of the object version deleted. DeleteMarkerVersionId *string // The name of the deleted object. @@ -671,17 +639,15 @@ type DeleteMarkerEntry struct { // Specifies whether Amazon S3 replicates delete markers. If you specify a Filter // in your replication configuration, you must also include a // DeleteMarkerReplication element. If your Filter includes a Tag element, the -// DeleteMarkerReplicationStatus must be set to Disabled, because Amazon S3 does +// DeleteMarkerReplication Status must be set to Disabled, because Amazon S3 does // not support replicating delete markers for tag-based rules. For an example -// configuration, see Basic Rule Configuration -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-add-config.html#replication-config-min-rule-config). -// For more information about delete marker replication, see Basic Rule -// Configuration -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/delete-marker-replication.html). -// If you are using an earlier version of the replication configuration, Amazon S3 -// handles replication of delete markers differently. For more information, see -// Backward Compatibility -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-add-config.html#replication-backward-compat-considerations). +// configuration, see Basic Rule Configuration (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-add-config.html#replication-config-min-rule-config) +// . For more information about delete marker replication, see Basic Rule +// Configuration (https://docs.aws.amazon.com/AmazonS3/latest/dev/delete-marker-replication.html) +// . If you are using an earlier version of the replication configuration, Amazon +// S3 handles replication of delete markers differently. For more information, see +// Backward Compatibility (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-add-config.html#replication-backward-compat-considerations) +// . type DeleteMarkerReplication struct { // Indicates whether to replicate delete markers. Indicates whether to replicate @@ -710,10 +676,10 @@ type Destination struct { // Destination bucket owner account ID. In a cross-account scenario, if you direct // Amazon S3 to change replica ownership to the Amazon Web Services account that - // owns the destination bucket by specifying the AccessControlTranslation property, - // this is the account ID of the destination bucket owner. For more information, - // see Replication Additional Configuration: Changing the Replica Owner - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-change-owner.html) + // owns the destination bucket by specifying the AccessControlTranslation + // property, this is the account ID of the destination bucket owner. For more + // information, see Replication Additional Configuration: Changing the Replica + // Owner (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-change-owner.html) // in the Amazon S3 User Guide. Account *string @@ -721,8 +687,8 @@ type Destination struct { // SourceSelectionCriteria is specified, you must specify this element. EncryptionConfiguration *EncryptionConfiguration - // A container specifying replication metrics-related settings enabling replication - // metrics and events. + // A container specifying replication metrics-related settings enabling + // replication metrics and events. Metrics *Metrics // A container specifying S3 Replication Time Control (S3 RTC), including whether @@ -733,8 +699,7 @@ type Destination struct { // The storage class to use when replicating objects, such as S3 Standard or // reduced redundancy. By default, Amazon S3 uses the storage class of the source // object to create the object replica. For valid values, see the StorageClass - // element of the PUT Bucket replication - // (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTreplication.html) + // element of the PUT Bucket replication (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTreplication.html) // action in the Amazon S3 API Reference. StorageClass StorageClass @@ -745,20 +710,19 @@ type Destination struct { type Encryption struct { // The server-side encryption algorithm used when storing job results in Amazon S3 - // (for example, AES256, aws:kms). + // (for example, AES256, aws:kms ). // // This member is required. EncryptionType ServerSideEncryption - // If the encryption type is aws:kms, this optional value can be used to specify + // If the encryption type is aws:kms , this optional value can be used to specify // the encryption context for the restore results. KMSContext *string - // If the encryption type is aws:kms, this optional value specifies the ID of the - // symmetric customer managed key to use for encryption of job results. Amazon S3 - // only supports symmetric keys. For more information, see Using symmetric and - // asymmetric keys - // (https://docs.aws.amazon.com/kms/latest/developerguide/symmetric-asymmetric.html) + // If the encryption type is aws:kms , this optional value specifies the ID of the + // symmetric encryption customer managed key to use for encryption of job results. + // Amazon S3 only supports symmetric encryption KMS keys. For more information, see + // Asymmetric keys in KMS (https://docs.aws.amazon.com/kms/latest/developerguide/symmetric-asymmetric.html) // in the Amazon Web Services Key Management Service Developer Guide. KMSKeyId *string @@ -772,9 +736,8 @@ type EncryptionConfiguration struct { // Specifies the ID (Key ARN or Alias ARN) of the customer managed Amazon Web // Services KMS key stored in Amazon Web Services Key Management Service (KMS) for // the destination bucket. Amazon S3 uses this key to encrypt replica objects. - // Amazon S3 only supports symmetric, customer managed KMS keys. For more - // information, see Using symmetric and asymmetric keys - // (https://docs.aws.amazon.com/kms/latest/developerguide/symmetric-asymmetric.html) + // Amazon S3 only supports symmetric encryption KMS keys. For more information, see + // Asymmetric keys in Amazon Web Services KMS (https://docs.aws.amazon.com/kms/latest/developerguide/symmetric-asymmetric.html) // in the Amazon Web Services Key Management Service Developer Guide. ReplicaKmsKeyID *string @@ -783,7 +746,7 @@ type EncryptionConfiguration struct { // A message that indicates the request is complete and no more messages will be // sent. You should not assume that the request is complete until the client -// receives an EndEvent. +// receives an EndEvent . type EndEvent struct { noSmithyDocumentSerde } @@ -793,934 +756,415 @@ type Error struct { // The error code is a string that uniquely identifies an error condition. It is // meant to be read and understood by programs that detect and handle errors by - // type. Amazon S3 error codes - // - // * Code: AccessDenied - // - // * Description: Access - // Denied - // - // * HTTP Status Code: 403 Forbidden - // - // * SOAP Fault Code Prefix: Client - // - // * - // Code: AccountProblem - // - // * Description: There is a problem with your Amazon Web - // Services account that prevents the action from completing successfully. Contact - // Amazon Web Services Support for further assistance. - // - // * HTTP Status Code: 403 - // Forbidden - // - // * SOAP Fault Code Prefix: Client - // - // * Code: AllAccessDisabled - // - // * - // Description: All access to this Amazon S3 resource has been disabled. Contact - // Amazon Web Services Support for further assistance. - // - // * HTTP Status Code: 403 - // Forbidden - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // AmbiguousGrantByEmailAddress - // - // * Description: The email address you provided is - // associated with more than one account. - // - // * HTTP Status Code: 400 Bad Request - // - // * - // SOAP Fault Code Prefix: Client - // - // * Code: AuthorizationHeaderMalformed - // - // * - // Description: The authorization header you provided is invalid. - // - // * HTTP Status - // Code: 400 Bad Request - // - // * HTTP Status Code: N/A - // - // * Code: BadDigest - // - // * - // Description: The Content-MD5 you specified did not match what we received. - // - // * - // HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // BucketAlreadyExists - // - // * Description: The requested bucket name is not available. - // The bucket namespace is shared by all users of the system. Please select a - // different name and try again. - // - // * HTTP Status Code: 409 Conflict - // - // * SOAP Fault - // Code Prefix: Client - // - // * Code: BucketAlreadyOwnedByYou - // - // * Description: The bucket - // you tried to create already exists, and you own it. Amazon S3 returns this error - // in all Amazon Web Services Regions except in the North Virginia Region. For - // legacy compatibility, if you re-create an existing bucket that you already own - // in the North Virginia Region, Amazon S3 returns 200 OK and resets the bucket - // access control lists (ACLs). - // - // * Code: 409 Conflict (in all Regions except the - // North Virginia Region) - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // BucketNotEmpty - // - // * Description: The bucket you tried to delete is not empty. - // - // * - // HTTP Status Code: 409 Conflict - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // CredentialsNotSupported - // - // * Description: This request does not support - // credentials. - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: - // Client - // - // * Code: CrossLocationLoggingProhibited - // - // * Description: Cross-location - // logging not allowed. Buckets in one geographic location cannot log information - // to a bucket in another location. - // - // * HTTP Status Code: 403 Forbidden - // - // * SOAP - // Fault Code Prefix: Client - // - // * Code: EntityTooSmall - // - // * Description: Your proposed - // upload is smaller than the minimum allowed object size. - // - // * HTTP Status Code: 400 - // Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: EntityTooLarge - // - // * - // Description: Your proposed upload exceeds the maximum allowed object size. - // - // * - // HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // ExpiredToken - // - // * Description: The provided token has expired. - // - // * HTTP Status - // Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // IllegalVersioningConfigurationException - // - // * Description: Indicates that the - // versioning configuration specified in the request is invalid. - // - // * HTTP Status - // Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // IncompleteBody - // - // * Description: You did not provide the number of bytes specified - // by the Content-Length HTTP header - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP - // Fault Code Prefix: Client - // - // * Code: IncorrectNumberOfFilesInPostRequest - // - // * - // Description: POST requires exactly one file upload per request. - // - // * HTTP Status - // Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // InlineDataTooLarge - // - // * Description: Inline data exceeds the maximum allowed - // size. - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * - // Code: InternalError - // - // * Description: We encountered an internal error. Please try - // again. - // - // * HTTP Status Code: 500 Internal Server Error - // - // * SOAP Fault Code Prefix: - // Server - // - // * Code: InvalidAccessKeyId - // - // * Description: The Amazon Web Services - // access key ID you provided does not exist in our records. - // - // * HTTP Status Code: - // 403 Forbidden - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // InvalidAddressingHeader - // - // * Description: You must specify the Anonymous role. - // - // * - // HTTP Status Code: N/A - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // InvalidArgument - // - // * Description: Invalid Argument - // - // * HTTP Status Code: 400 Bad - // Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: InvalidBucketName - // - // * - // Description: The specified bucket is not valid. - // - // * HTTP Status Code: 400 Bad - // Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: InvalidBucketState - // - // * - // Description: The request is not valid with the current state of the bucket. - // - // * - // HTTP Status Code: 409 Conflict - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // InvalidDigest - // - // * Description: The Content-MD5 you specified is not valid. - // - // * - // HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // InvalidEncryptionAlgorithmError - // - // * Description: The encryption request you - // specified is not valid. The valid value is AES256. - // - // * HTTP Status Code: 400 Bad - // Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: InvalidLocationConstraint - // - // * - // Description: The specified location constraint is not valid. For more - // information about Regions, see How to Select a Region for Your Buckets - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro). - // - // * - // HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // InvalidObjectState - // - // * Description: The action is not valid for the current state - // of the object. - // - // * HTTP Status Code: 403 Forbidden - // - // * SOAP Fault Code Prefix: - // Client - // - // * Code: InvalidPart - // - // * Description: One or more of the specified parts - // could not be found. The part might not have been uploaded, or the specified - // entity tag might not have matched the part's entity tag. - // - // * HTTP Status Code: - // 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: InvalidPartOrder - // - // * - // Description: The list of parts was not in ascending order. Parts list must be - // specified in order by part number. - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP - // Fault Code Prefix: Client - // - // * Code: InvalidPayer - // - // * Description: All access to - // this object has been disabled. Please contact Amazon Web Services Support for - // further assistance. - // - // * HTTP Status Code: 403 Forbidden - // - // * SOAP Fault Code - // Prefix: Client - // - // * Code: InvalidPolicyDocument - // - // * Description: The content of the - // form does not meet the conditions specified in the policy document. - // - // * HTTP - // Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // InvalidRange - // - // * Description: The requested range cannot be satisfied. - // - // * HTTP - // Status Code: 416 Requested Range Not Satisfiable - // - // * SOAP Fault Code Prefix: - // Client - // - // * Code: InvalidRequest - // - // * Description: Please use AWS4-HMAC-SHA256. - // - // * - // HTTP Status Code: 400 Bad Request - // - // * Code: N/A - // - // * Code: InvalidRequest - // - // * - // Description: SOAP requests must be made over an HTTPS connection. - // - // * HTTP Status - // Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // InvalidRequest - // - // * Description: Amazon S3 Transfer Acceleration is not supported - // for buckets with non-DNS compliant names. - // - // * HTTP Status Code: 400 Bad - // Request - // - // * Code: N/A - // - // * Code: InvalidRequest - // - // * Description: Amazon S3 Transfer - // Acceleration is not supported for buckets with periods (.) in their names. - // - // * - // HTTP Status Code: 400 Bad Request - // - // * Code: N/A - // - // * Code: InvalidRequest - // - // * - // Description: Amazon S3 Transfer Accelerate endpoint only supports virtual style - // requests. - // - // * HTTP Status Code: 400 Bad Request - // - // * Code: N/A - // - // * Code: - // InvalidRequest - // - // * Description: Amazon S3 Transfer Accelerate is not configured - // on this bucket. - // - // * HTTP Status Code: 400 Bad Request - // - // * Code: N/A - // - // * Code: - // InvalidRequest - // - // * Description: Amazon S3 Transfer Accelerate is disabled on this - // bucket. - // - // * HTTP Status Code: 400 Bad Request - // - // * Code: N/A - // - // * Code: - // InvalidRequest - // - // * Description: Amazon S3 Transfer Acceleration is not supported - // on this bucket. Contact Amazon Web Services Support for more information. - // - // * - // HTTP Status Code: 400 Bad Request - // - // * Code: N/A - // - // * Code: InvalidRequest - // - // * - // Description: Amazon S3 Transfer Acceleration cannot be enabled on this bucket. - // Contact Amazon Web Services Support for more information. - // - // * HTTP Status Code: - // 400 Bad Request - // - // * Code: N/A - // - // * Code: InvalidSecurity - // - // * Description: The - // provided security credentials are not valid. - // - // * HTTP Status Code: 403 - // Forbidden - // - // * SOAP Fault Code Prefix: Client - // - // * Code: InvalidSOAPRequest - // - // * - // Description: The SOAP request body is invalid. - // - // * HTTP Status Code: 400 Bad - // Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: InvalidStorageClass - // - // * - // Description: The storage class you specified is not valid. - // - // * HTTP Status Code: - // 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // InvalidTargetBucketForLogging - // - // * Description: The target bucket for logging does - // not exist, is not owned by you, or does not have the appropriate grants for the - // log-delivery group. - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code - // Prefix: Client - // - // * Code: InvalidToken - // - // * Description: The provided token is - // malformed or otherwise invalid. - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP - // Fault Code Prefix: Client - // - // * Code: InvalidURI - // - // * Description: Couldn't parse the - // specified URI. - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: - // Client - // - // * Code: KeyTooLongError - // - // * Description: Your key is too long. - // - // * HTTP - // Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // MalformedACLError - // - // * Description: The XML you provided was not well-formed or - // did not validate against our published schema. - // - // * HTTP Status Code: 400 Bad - // Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: MalformedPOSTRequest - // - // * - // Description: The body of your POST request is not well-formed - // multipart/form-data. - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code - // Prefix: Client - // - // * Code: MalformedXML - // - // * Description: This happens when the user - // sends malformed XML (XML that doesn't conform to the published XSD) for the - // configuration. The error message is, "The XML you provided was not well-formed - // or did not validate against our published schema." - // - // * HTTP Status Code: 400 Bad - // Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: MaxMessageLengthExceeded - // - // * - // Description: Your request was too big. - // - // * HTTP Status Code: 400 Bad Request - // - // * - // SOAP Fault Code Prefix: Client - // - // * Code: MaxPostPreDataLengthExceededError - // - // * - // Description: Your POST request fields preceding the upload file were too - // large. - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * - // Code: MetadataTooLarge - // - // * Description: Your metadata headers exceed the maximum - // allowed metadata size. - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code - // Prefix: Client - // - // * Code: MethodNotAllowed - // - // * Description: The specified method is - // not allowed against this resource. - // - // * HTTP Status Code: 405 Method Not - // Allowed - // - // * SOAP Fault Code Prefix: Client - // - // * Code: MissingAttachment - // - // * - // Description: A SOAP attachment was expected, but none were found. - // - // * HTTP Status - // Code: N/A - // - // * SOAP Fault Code Prefix: Client - // - // * Code: MissingContentLength - // - // * - // Description: You must provide the Content-Length HTTP header. - // - // * HTTP Status - // Code: 411 Length Required - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // MissingRequestBodyError - // - // * Description: This happens when the user sends an - // empty XML document as a request. The error message is, "Request body is - // empty." - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: - // Client - // - // * Code: MissingSecurityElement - // - // * Description: The SOAP 1.1 request is - // missing a security element. - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP Fault - // Code Prefix: Client - // - // * Code: MissingSecurityHeader - // - // * Description: Your request - // is missing a required header. - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP Fault - // Code Prefix: Client - // - // * Code: NoLoggingStatusForKey - // - // * Description: There is no - // such thing as a logging status subresource for a key. - // - // * HTTP Status Code: 400 - // Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: NoSuchBucket - // - // * - // Description: The specified bucket does not exist. - // - // * HTTP Status Code: 404 Not - // Found - // - // * SOAP Fault Code Prefix: Client - // - // * Code: NoSuchBucketPolicy - // - // * - // Description: The specified bucket does not have a bucket policy. - // - // * HTTP Status - // Code: 404 Not Found - // - // * SOAP Fault Code Prefix: Client - // - // * Code: NoSuchKey - // - // * - // Description: The specified key does not exist. - // - // * HTTP Status Code: 404 Not - // Found - // - // * SOAP Fault Code Prefix: Client - // - // * Code: NoSuchLifecycleConfiguration - // - // * - // Description: The lifecycle configuration does not exist. - // - // * HTTP Status Code: - // 404 Not Found - // - // * SOAP Fault Code Prefix: Client - // - // * Code: NoSuchUpload - // - // * - // Description: The specified multipart upload does not exist. The upload ID might - // be invalid, or the multipart upload might have been aborted or completed. - // - // * - // HTTP Status Code: 404 Not Found - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // NoSuchVersion - // - // * Description: Indicates that the version ID specified in the - // request does not match an existing version. - // - // * HTTP Status Code: 404 Not - // Found - // - // * SOAP Fault Code Prefix: Client - // - // * Code: NotImplemented - // - // * Description: - // A header you provided implies functionality that is not implemented. - // - // * HTTP - // Status Code: 501 Not Implemented - // - // * SOAP Fault Code Prefix: Server - // - // * Code: - // NotSignedUp - // - // * Description: Your account is not signed up for the Amazon S3 - // service. You must sign up before you can use Amazon S3. You can sign up at the - // following URL: Amazon S3 (http://aws.amazon.com/s3) - // - // * HTTP Status Code: 403 - // Forbidden - // - // * SOAP Fault Code Prefix: Client - // - // * Code: OperationAborted - // - // * - // Description: A conflicting conditional action is currently in progress against - // this resource. Try again. - // - // * HTTP Status Code: 409 Conflict - // - // * SOAP Fault Code - // Prefix: Client - // - // * Code: PermanentRedirect - // - // * Description: The bucket you are - // attempting to access must be addressed using the specified endpoint. Send all - // future requests to this endpoint. - // - // * HTTP Status Code: 301 Moved Permanently - // - // * - // SOAP Fault Code Prefix: Client - // - // * Code: PreconditionFailed - // - // * Description: At - // least one of the preconditions you specified did not hold. - // - // * HTTP Status Code: - // 412 Precondition Failed - // - // * SOAP Fault Code Prefix: Client - // - // * Code: Redirect - // - // * - // Description: Temporary redirect. - // - // * HTTP Status Code: 307 Moved Temporarily - // - // * - // SOAP Fault Code Prefix: Client - // - // * Code: RestoreAlreadyInProgress - // - // * Description: - // Object restore is already in progress. - // - // * HTTP Status Code: 409 Conflict - // - // * SOAP - // Fault Code Prefix: Client - // - // * Code: RequestIsNotMultiPartContent - // - // * Description: - // Bucket POST must be of the enclosure-type multipart/form-data. - // - // * HTTP Status - // Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // RequestTimeout - // - // * Description: Your socket connection to the server was not read - // from or written to within the timeout period. - // - // * HTTP Status Code: 400 Bad - // Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: RequestTimeTooSkewed - // - // * - // Description: The difference between the request time and the server's time is - // too large. - // - // * HTTP Status Code: 403 Forbidden - // - // * SOAP Fault Code Prefix: - // Client - // - // * Code: RequestTorrentOfBucketError - // - // * Description: Requesting the - // torrent file of a bucket is not permitted. - // - // * HTTP Status Code: 400 Bad - // Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: SignatureDoesNotMatch - // - // * - // Description: The request signature we calculated does not match the signature - // you provided. Check your Amazon Web Services secret access key and signing - // method. For more information, see REST Authentication - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html) and - // SOAP Authentication - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/SOAPAuthentication.html) for - // details. - // - // * HTTP Status Code: 403 Forbidden - // - // * SOAP Fault Code Prefix: Client - // - // * - // Code: ServiceUnavailable - // - // * Description: Reduce your request rate. - // - // * HTTP - // Status Code: 503 Service Unavailable - // - // * SOAP Fault Code Prefix: Server - // - // * Code: - // SlowDown - // - // * Description: Reduce your request rate. - // - // * HTTP Status Code: 503 Slow - // Down - // - // * SOAP Fault Code Prefix: Server - // - // * Code: TemporaryRedirect - // - // * - // Description: You are being redirected to the bucket while DNS updates. - // - // * HTTP - // Status Code: 307 Moved Temporarily - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // TokenRefreshRequired - // - // * Description: The provided token must be refreshed. - // - // * - // HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // TooManyBuckets - // - // * Description: You have attempted to create more buckets than - // allowed. - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: - // Client - // - // * Code: UnexpectedContent - // - // * Description: This request does not support - // content. - // - // * HTTP Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: - // Client - // - // * Code: UnresolvableGrantByEmailAddress - // - // * Description: The email - // address you provided does not match any account on record. - // - // * HTTP Status Code: - // 400 Bad Request - // - // * SOAP Fault Code Prefix: Client - // - // * Code: - // UserKeyMustBeSpecified - // - // * Description: The bucket POST must contain the - // specified field name. If it is specified, check the order of the fields. - // - // * HTTP - // Status Code: 400 Bad Request - // - // * SOAP Fault Code Prefix: Client + // type. The following is a list of Amazon S3 error codes. For more information, + // see Error responses (https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html) + // . + // - Code: AccessDenied + // - Description: Access Denied + // - HTTP Status Code: 403 Forbidden + // - SOAP Fault Code Prefix: Client + // - Code: AccountProblem + // - Description: There is a problem with your Amazon Web Services account that + // prevents the action from completing successfully. Contact Amazon Web Services + // Support for further assistance. + // - HTTP Status Code: 403 Forbidden + // - SOAP Fault Code Prefix: Client + // - Code: AllAccessDisabled + // - Description: All access to this Amazon S3 resource has been disabled. + // Contact Amazon Web Services Support for further assistance. + // - HTTP Status Code: 403 Forbidden + // - SOAP Fault Code Prefix: Client + // - Code: AmbiguousGrantByEmailAddress + // - Description: The email address you provided is associated with more than + // one account. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: AuthorizationHeaderMalformed + // - Description: The authorization header you provided is invalid. + // - HTTP Status Code: 400 Bad Request + // - HTTP Status Code: N/A + // - Code: BadDigest + // - Description: The Content-MD5 you specified did not match what we received. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: BucketAlreadyExists + // - Description: The requested bucket name is not available. The bucket + // namespace is shared by all users of the system. Please select a different name + // and try again. + // - HTTP Status Code: 409 Conflict + // - SOAP Fault Code Prefix: Client + // - Code: BucketAlreadyOwnedByYou + // - Description: The bucket you tried to create already exists, and you own it. + // Amazon S3 returns this error in all Amazon Web Services Regions except in the + // North Virginia Region. For legacy compatibility, if you re-create an existing + // bucket that you already own in the North Virginia Region, Amazon S3 returns 200 + // OK and resets the bucket access control lists (ACLs). + // - Code: 409 Conflict (in all Regions except the North Virginia Region) + // - SOAP Fault Code Prefix: Client + // - Code: BucketNotEmpty + // - Description: The bucket you tried to delete is not empty. + // - HTTP Status Code: 409 Conflict + // - SOAP Fault Code Prefix: Client + // - Code: CredentialsNotSupported + // - Description: This request does not support credentials. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: CrossLocationLoggingProhibited + // - Description: Cross-location logging not allowed. Buckets in one geographic + // location cannot log information to a bucket in another location. + // - HTTP Status Code: 403 Forbidden + // - SOAP Fault Code Prefix: Client + // - Code: EntityTooSmall + // - Description: Your proposed upload is smaller than the minimum allowed + // object size. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: EntityTooLarge + // - Description: Your proposed upload exceeds the maximum allowed object size. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: ExpiredToken + // - Description: The provided token has expired. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: IllegalVersioningConfigurationException + // - Description: Indicates that the versioning configuration specified in the + // request is invalid. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: IncompleteBody + // - Description: You did not provide the number of bytes specified by the + // Content-Length HTTP header + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: IncorrectNumberOfFilesInPostRequest + // - Description: POST requires exactly one file upload per request. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InlineDataTooLarge + // - Description: Inline data exceeds the maximum allowed size. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InternalError + // - Description: We encountered an internal error. Please try again. + // - HTTP Status Code: 500 Internal Server Error + // - SOAP Fault Code Prefix: Server + // - Code: InvalidAccessKeyId + // - Description: The Amazon Web Services access key ID you provided does not + // exist in our records. + // - HTTP Status Code: 403 Forbidden + // - SOAP Fault Code Prefix: Client + // - Code: InvalidAddressingHeader + // - Description: You must specify the Anonymous role. + // - HTTP Status Code: N/A + // - SOAP Fault Code Prefix: Client + // - Code: InvalidArgument + // - Description: Invalid Argument + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InvalidBucketName + // - Description: The specified bucket is not valid. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InvalidBucketState + // - Description: The request is not valid with the current state of the bucket. + // - HTTP Status Code: 409 Conflict + // - SOAP Fault Code Prefix: Client + // - Code: InvalidDigest + // - Description: The Content-MD5 you specified is not valid. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InvalidEncryptionAlgorithmError + // - Description: The encryption request you specified is not valid. The valid + // value is AES256. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InvalidLocationConstraint + // - Description: The specified location constraint is not valid. For more + // information about Regions, see How to Select a Region for Your Buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro) + // . + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InvalidObjectState + // - Description: The action is not valid for the current state of the object. + // - HTTP Status Code: 403 Forbidden + // - SOAP Fault Code Prefix: Client + // - Code: InvalidPart + // - Description: One or more of the specified parts could not be found. The + // part might not have been uploaded, or the specified entity tag might not have + // matched the part's entity tag. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InvalidPartOrder + // - Description: The list of parts was not in ascending order. Parts list must + // be specified in order by part number. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InvalidPayer + // - Description: All access to this object has been disabled. Please contact + // Amazon Web Services Support for further assistance. + // - HTTP Status Code: 403 Forbidden + // - SOAP Fault Code Prefix: Client + // - Code: InvalidPolicyDocument + // - Description: The content of the form does not meet the conditions specified + // in the policy document. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InvalidRange + // - Description: The requested range cannot be satisfied. + // - HTTP Status Code: 416 Requested Range Not Satisfiable + // - SOAP Fault Code Prefix: Client + // - Code: InvalidRequest + // - Description: Please use AWS4-HMAC-SHA256 . + // - HTTP Status Code: 400 Bad Request + // - Code: N/A + // - Code: InvalidRequest + // - Description: SOAP requests must be made over an HTTPS connection. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InvalidRequest + // - Description: Amazon S3 Transfer Acceleration is not supported for buckets + // with non-DNS compliant names. + // - HTTP Status Code: 400 Bad Request + // - Code: N/A + // - Code: InvalidRequest + // - Description: Amazon S3 Transfer Acceleration is not supported for buckets + // with periods (.) in their names. + // - HTTP Status Code: 400 Bad Request + // - Code: N/A + // - Code: InvalidRequest + // - Description: Amazon S3 Transfer Accelerate endpoint only supports virtual + // style requests. + // - HTTP Status Code: 400 Bad Request + // - Code: N/A + // - Code: InvalidRequest + // - Description: Amazon S3 Transfer Accelerate is not configured on this + // bucket. + // - HTTP Status Code: 400 Bad Request + // - Code: N/A + // - Code: InvalidRequest + // - Description: Amazon S3 Transfer Accelerate is disabled on this bucket. + // - HTTP Status Code: 400 Bad Request + // - Code: N/A + // - Code: InvalidRequest + // - Description: Amazon S3 Transfer Acceleration is not supported on this + // bucket. Contact Amazon Web Services Support for more information. + // - HTTP Status Code: 400 Bad Request + // - Code: N/A + // - Code: InvalidRequest + // - Description: Amazon S3 Transfer Acceleration cannot be enabled on this + // bucket. Contact Amazon Web Services Support for more information. + // - HTTP Status Code: 400 Bad Request + // - Code: N/A + // - Code: InvalidSecurity + // - Description: The provided security credentials are not valid. + // - HTTP Status Code: 403 Forbidden + // - SOAP Fault Code Prefix: Client + // - Code: InvalidSOAPRequest + // - Description: The SOAP request body is invalid. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InvalidStorageClass + // - Description: The storage class you specified is not valid. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InvalidTargetBucketForLogging + // - Description: The target bucket for logging does not exist, is not owned by + // you, or does not have the appropriate grants for the log-delivery group. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InvalidToken + // - Description: The provided token is malformed or otherwise invalid. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: InvalidURI + // - Description: Couldn't parse the specified URI. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: KeyTooLongError + // - Description: Your key is too long. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: MalformedACLError + // - Description: The XML you provided was not well-formed or did not validate + // against our published schema. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: MalformedPOSTRequest + // - Description: The body of your POST request is not well-formed + // multipart/form-data. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: MalformedXML + // - Description: This happens when the user sends malformed XML (XML that + // doesn't conform to the published XSD) for the configuration. The error message + // is, "The XML you provided was not well-formed or did not validate against our + // published schema." + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: MaxMessageLengthExceeded + // - Description: Your request was too big. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: MaxPostPreDataLengthExceededError + // - Description: Your POST request fields preceding the upload file were too + // large. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: MetadataTooLarge + // - Description: Your metadata headers exceed the maximum allowed metadata + // size. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: MethodNotAllowed + // - Description: The specified method is not allowed against this resource. + // - HTTP Status Code: 405 Method Not Allowed + // - SOAP Fault Code Prefix: Client + // - Code: MissingAttachment + // - Description: A SOAP attachment was expected, but none were found. + // - HTTP Status Code: N/A + // - SOAP Fault Code Prefix: Client + // - Code: MissingContentLength + // - Description: You must provide the Content-Length HTTP header. + // - HTTP Status Code: 411 Length Required + // - SOAP Fault Code Prefix: Client + // - Code: MissingRequestBodyError + // - Description: This happens when the user sends an empty XML document as a + // request. The error message is, "Request body is empty." + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: MissingSecurityElement + // - Description: The SOAP 1.1 request is missing a security element. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: MissingSecurityHeader + // - Description: Your request is missing a required header. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: NoLoggingStatusForKey + // - Description: There is no such thing as a logging status subresource for a + // key. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: NoSuchBucket + // - Description: The specified bucket does not exist. + // - HTTP Status Code: 404 Not Found + // - SOAP Fault Code Prefix: Client + // - Code: NoSuchBucketPolicy + // - Description: The specified bucket does not have a bucket policy. + // - HTTP Status Code: 404 Not Found + // - SOAP Fault Code Prefix: Client + // - Code: NoSuchKey + // - Description: The specified key does not exist. + // - HTTP Status Code: 404 Not Found + // - SOAP Fault Code Prefix: Client + // - Code: NoSuchLifecycleConfiguration + // - Description: The lifecycle configuration does not exist. + // - HTTP Status Code: 404 Not Found + // - SOAP Fault Code Prefix: Client + // - Code: NoSuchUpload + // - Description: The specified multipart upload does not exist. The upload ID + // might be invalid, or the multipart upload might have been aborted or completed. + // - HTTP Status Code: 404 Not Found + // - SOAP Fault Code Prefix: Client + // - Code: NoSuchVersion + // - Description: Indicates that the version ID specified in the request does + // not match an existing version. + // - HTTP Status Code: 404 Not Found + // - SOAP Fault Code Prefix: Client + // - Code: NotImplemented + // - Description: A header you provided implies functionality that is not + // implemented. + // - HTTP Status Code: 501 Not Implemented + // - SOAP Fault Code Prefix: Server + // - Code: NotSignedUp + // - Description: Your account is not signed up for the Amazon S3 service. You + // must sign up before you can use Amazon S3. You can sign up at the following URL: + // Amazon S3 (http://aws.amazon.com/s3) + // - HTTP Status Code: 403 Forbidden + // - SOAP Fault Code Prefix: Client + // - Code: OperationAborted + // - Description: A conflicting conditional action is currently in progress + // against this resource. Try again. + // - HTTP Status Code: 409 Conflict + // - SOAP Fault Code Prefix: Client + // - Code: PermanentRedirect + // - Description: The bucket you are attempting to access must be addressed + // using the specified endpoint. Send all future requests to this endpoint. + // - HTTP Status Code: 301 Moved Permanently + // - SOAP Fault Code Prefix: Client + // - Code: PreconditionFailed + // - Description: At least one of the preconditions you specified did not hold. + // - HTTP Status Code: 412 Precondition Failed + // - SOAP Fault Code Prefix: Client + // - Code: Redirect + // - Description: Temporary redirect. + // - HTTP Status Code: 307 Moved Temporarily + // - SOAP Fault Code Prefix: Client + // - Code: RestoreAlreadyInProgress + // - Description: Object restore is already in progress. + // - HTTP Status Code: 409 Conflict + // - SOAP Fault Code Prefix: Client + // - Code: RequestIsNotMultiPartContent + // - Description: Bucket POST must be of the enclosure-type multipart/form-data. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: RequestTimeout + // - Description: Your socket connection to the server was not read from or + // written to within the timeout period. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: RequestTimeTooSkewed + // - Description: The difference between the request time and the server's time + // is too large. + // - HTTP Status Code: 403 Forbidden + // - SOAP Fault Code Prefix: Client + // - Code: RequestTorrentOfBucketError + // - Description: Requesting the torrent file of a bucket is not permitted. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: SignatureDoesNotMatch + // - Description: The request signature we calculated does not match the + // signature you provided. Check your Amazon Web Services secret access key and + // signing method. For more information, see REST Authentication (https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html) + // and SOAP Authentication (https://docs.aws.amazon.com/AmazonS3/latest/dev/SOAPAuthentication.html) + // for details. + // - HTTP Status Code: 403 Forbidden + // - SOAP Fault Code Prefix: Client + // - Code: ServiceUnavailable + // - Description: Service is unable to handle request. + // - HTTP Status Code: 503 Service Unavailable + // - SOAP Fault Code Prefix: Server + // - Code: SlowDown + // - Description: Reduce your request rate. + // - HTTP Status Code: 503 Slow Down + // - SOAP Fault Code Prefix: Server + // - Code: TemporaryRedirect + // - Description: You are being redirected to the bucket while DNS updates. + // - HTTP Status Code: 307 Moved Temporarily + // - SOAP Fault Code Prefix: Client + // - Code: TokenRefreshRequired + // - Description: The provided token must be refreshed. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: TooManyBuckets + // - Description: You have attempted to create more buckets than allowed. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: UnexpectedContent + // - Description: This request does not support content. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: UnresolvableGrantByEmailAddress + // - Description: The email address you provided does not match any account on + // record. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client + // - Code: UserKeyMustBeSpecified + // - Description: The bucket POST must contain the specified field name. If it + // is specified, check the order of the fields. + // - HTTP Status Code: 400 Bad Request + // - SOAP Fault Code Prefix: Client Code *string // The error key. @@ -1745,9 +1189,9 @@ type ErrorDocument struct { // The object key name to use when a 4XX class error occurs. Replacement must be // made for object keys containing special characters (such as carriage returns) - // when using XML requests. For more information, see XML related object key - // constraints - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints). + // when using XML requests. For more information, see XML related object key + // constraints (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints) + // . // // This member is required. Key *string @@ -1761,12 +1205,11 @@ type EventBridgeConfiguration struct { } // Optional configuration to replicate existing source bucket objects. For more -// information, see Replicating Existing Objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-what-is-isnot-replicated.html#existing-object-replication) +// information, see Replicating Existing Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-what-is-isnot-replicated.html#existing-object-replication) // in the Amazon S3 User Guide. type ExistingObjectReplication struct { - // + // Specifies whether Amazon S3 replicates existing source bucket objects. // // This member is required. Status ExistingObjectReplicationStatus @@ -1781,9 +1224,8 @@ type FilterRule struct { // The object key name prefix or suffix identifying one or more objects to which // the filtering rule applies. The maximum length is 1,024 characters. Overlapping // prefixes and suffixes are not supported. For more information, see Configuring - // Event Notifications - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) in the - // Amazon S3 User Guide. + // Event Notifications (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) + // in the Amazon S3 User Guide. Name FilterRuleName // The value that the filter searches for in object key names. @@ -1855,32 +1297,19 @@ type Grantee struct { // Screen name of the grantee. DisplayName *string - // Email address of the grantee. Using email addresses to specify a grantee is only - // supported in the following Amazon Web Services Regions: - // - // * US East (N. - // Virginia) - // - // * US West (N. California) - // - // * US West (Oregon) - // - // * Asia Pacific - // (Singapore) - // - // * Asia Pacific (Sydney) - // - // * Asia Pacific (Tokyo) - // - // * Europe - // (Ireland) - // - // * South America (São Paulo) - // - // For a list of all the Amazon S3 - // supported Regions and endpoints, see Regions and Endpoints - // (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the - // Amazon Web Services General Reference. + // Email address of the grantee. Using email addresses to specify a grantee is + // only supported in the following Amazon Web Services Regions: + // - US East (N. Virginia) + // - US West (N. California) + // - US West (Oregon) + // - Asia Pacific (Singapore) + // - Asia Pacific (Sydney) + // - Asia Pacific (Tokyo) + // - Europe (Ireland) + // - South America (São Paulo) + // For a list of all the Amazon S3 supported Regions and endpoints, see Regions + // and Endpoints (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) + // in the Amazon Web Services General Reference. EmailAddress *string // The canonical user ID of the grantee. @@ -1901,8 +1330,8 @@ type IndexDocument struct { // key name images/index.html) The suffix must not be empty and must not include a // slash character. Replacement must be made for object keys containing special // characters (such as carriage returns) when using XML requests. For more - // information, see XML related object key constraints - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints). + // information, see XML related object key constraints (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints) + // . // // This member is required. Suffix *string @@ -1942,8 +1371,8 @@ type InputSerialization struct { noSmithyDocumentSerde } -// A container for specifying S3 Intelligent-Tiering filters. The filters determine -// the subset of objects to which the rule applies. +// A container for specifying S3 Intelligent-Tiering filters. The filters +// determine the subset of objects to which the rule applies. type IntelligentTieringAndOperator struct { // An object key name prefix that identifies the subset of objects to which the @@ -1959,8 +1388,8 @@ type IntelligentTieringAndOperator struct { // Specifies the S3 Intelligent-Tiering configuration for an Amazon S3 bucket. For // information about the S3 Intelligent-Tiering storage class, see Storage class -// for automatically optimizing frequently and infrequently accessed objects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access). +// for automatically optimizing frequently and infrequently accessed objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access) +// . type IntelligentTieringConfiguration struct { // The ID used to identify the S3 Intelligent-Tiering configuration. @@ -1978,8 +1407,8 @@ type IntelligentTieringConfiguration struct { // This member is required. Tierings []Tiering - // Specifies a bucket filter. The configuration only includes objects that meet the - // filter's criteria. + // Specifies a bucket filter. The configuration only includes objects that meet + // the filter's criteria. Filter *IntelligentTieringFilter noSmithyDocumentSerde @@ -1989,16 +1418,16 @@ type IntelligentTieringConfiguration struct { // configuration applies to. type IntelligentTieringFilter struct { - // A conjunction (logical AND) of predicates, which is used in evaluating a metrics - // filter. The operator must have at least two predicates, and an object must match - // all of the predicates in order for the filter to apply. + // A conjunction (logical AND) of predicates, which is used in evaluating a + // metrics filter. The operator must have at least two predicates, and an object + // must match all of the predicates in order for the filter to apply. And *IntelligentTieringAndOperator // An object key name prefix that identifies the subset of objects to which the // rule applies. Replacement must be made for object keys containing special // characters (such as carriage returns) when using XML requests. For more - // information, see XML related object key constraints - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints). + // information, see XML related object key constraints (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints) + // . Prefix *string // A container of a key value name pair. @@ -2008,8 +1437,7 @@ type IntelligentTieringFilter struct { } // Specifies the inventory configuration for an Amazon S3 bucket. For more -// information, see GET Bucket inventory -// (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETInventoryConfig.html) +// information, see GET Bucket inventory (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETInventoryConfig.html) // in the Amazon S3 API Reference. type InventoryConfiguration struct { @@ -2023,16 +1451,16 @@ type InventoryConfiguration struct { // This member is required. Id *string - // Object versions to include in the inventory list. If set to All, the list + // Object versions to include in the inventory list. If set to All , the list // includes all the object versions, which adds the version-related fields - // VersionId, IsLatest, and DeleteMarker to the list. If set to Current, the list - // does not contain these version-related fields. + // VersionId , IsLatest , and DeleteMarker to the list. If set to Current , the + // list does not contain these version-related fields. // // This member is required. IncludedObjectVersions InventoryIncludedObjectVersions - // Specifies whether the inventory is enabled or disabled. If set to True, an - // inventory list is generated. If set to False, no inventory list is generated. + // Specifies whether the inventory is enabled or disabled. If set to True , an + // inventory list is generated. If set to False , no inventory list is generated. // // This member is required. IsEnabled bool @@ -2042,8 +1470,8 @@ type InventoryConfiguration struct { // This member is required. Schedule *InventorySchedule - // Specifies an inventory filter. The inventory only includes objects that meet the - // filter's criteria. + // Specifies an inventory filter. The inventory only includes objects that meet + // the filter's criteria. Filter *InventoryFilter // Contains the optional fields that are included in the inventory results. @@ -2077,8 +1505,8 @@ type InventoryEncryption struct { noSmithyDocumentSerde } -// Specifies an inventory filter. The inventory only includes objects that meet the -// filter's criteria. +// Specifies an inventory filter. The inventory only includes objects that meet +// the filter's criteria. type InventoryFilter struct { // The prefix that an object must have to be included in the inventory results. @@ -2154,9 +1582,8 @@ type JSONOutput struct { type LambdaFunctionConfiguration struct { // The Amazon S3 bucket event for which to invoke the Lambda function. For more - // information, see Supported Event Types - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) in the - // Amazon S3 User Guide. + // information, see Supported Event Types (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) + // in the Amazon S3 User Guide. // // This member is required. Events []Event @@ -2168,9 +1595,8 @@ type LambdaFunctionConfiguration struct { LambdaFunctionArn *string // Specifies object key name filtering rules. For information about key name - // filtering, see Configuring Event Notifications - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) in the - // Amazon S3 User Guide. + // filtering, see Configuring event notifications using object key name filtering (https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-filtering.html) + // in the Amazon S3 User Guide. Filter *NotificationConfigurationFilter // An optional unique identifier for configurations in a notification @@ -2180,11 +1606,13 @@ type LambdaFunctionConfiguration struct { noSmithyDocumentSerde } -// Container for the expiration for the lifecycle of the object. +// Container for the expiration for the lifecycle of the object. For more +// information see, Managing your storage lifecycle (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html) +// in the Amazon S3 User Guide. type LifecycleExpiration struct { - // Indicates at what date the object is to be moved or deleted. Should be in GMT - // ISO 8601 Format. + // Indicates at what date the object is to be moved or deleted. The date value + // must conform to the ISO 8601 format. The time is always midnight UTC. Date *time.Time // Indicates the lifetime, in days, of the objects that are subject to the rule. @@ -2200,7 +1628,9 @@ type LifecycleExpiration struct { noSmithyDocumentSerde } -// A lifecycle rule for individual objects in an Amazon S3 bucket. +// A lifecycle rule for individual objects in an Amazon S3 bucket. For more +// information see, Managing your storage lifecycle (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html) +// in the Amazon S3 User Guide. type LifecycleRule struct { // If 'Enabled', the rule is currently being applied. If 'Disabled', the rule is @@ -2211,9 +1641,8 @@ type LifecycleRule struct { // Specifies the days since the initiation of an incomplete multipart upload that // Amazon S3 will wait before permanently removing all parts of the upload. For - // more information, see Aborting Incomplete Multipart Uploads Using a Bucket - // Lifecycle Policy - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config) + // more information, see Aborting Incomplete Multipart Uploads Using a Bucket + // Lifecycle Configuration (https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config) // in the Amazon S3 User Guide. AbortIncompleteMultipartUpload *AbortIncompleteMultipartUpload @@ -2222,7 +1651,7 @@ type LifecycleRule struct { Expiration *LifecycleExpiration // The Filter is used to identify objects that a Lifecycle Rule applies to. A - // Filter must have exactly one of Prefix, Tag, or And specified. Filter is + // Filter must have exactly one of Prefix , Tag , or And specified. Filter is // required if the LifecycleRule does not contain a Prefix element. Filter LifecycleRuleFilter @@ -2246,8 +1675,8 @@ type LifecycleRule struct { // Prefix identifying one or more objects to which the rule applies. This is no // longer used; use Filter instead. Replacement must be made for object keys // containing special characters (such as carriage returns) when using XML - // requests. For more information, see XML related object key constraints - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints). + // requests. For more information, see XML related object key constraints (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints) + // . // // Deprecated: This member has been deprecated. Prefix *string @@ -2280,7 +1709,7 @@ type LifecycleRuleAndOperator struct { } // The Filter is used to identify objects that a Lifecycle Rule applies to. A -// Filter must have exactly one of Prefix, Tag, or And specified. +// Filter must have exactly one of Prefix , Tag , or And specified. // // The following types satisfy this interface: // @@ -2324,9 +1753,9 @@ func (*LifecycleRuleFilterMemberObjectSizeLessThan) isLifecycleRuleFilter() {} // Prefix identifying one or more objects to which the rule applies. Replacement // must be made for object keys containing special characters (such as carriage -// returns) when using XML requests. For more information, see XML related object -// key constraints -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints). +// returns) when using XML requests. For more information, see XML related object +// key constraints (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints) +// . type LifecycleRuleFilterMemberPrefix struct { Value string @@ -2344,10 +1773,9 @@ type LifecycleRuleFilterMemberTag struct { func (*LifecycleRuleFilterMemberTag) isLifecycleRuleFilter() {} -// Describes where logs are stored and the prefix that Amazon S3 assigns to all log -// object keys for a bucket. For more information, see PUT Bucket logging -// (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlogging.html) in -// the Amazon S3 API Reference. +// Describes where logs are stored and the prefix that Amazon S3 assigns to all +// log object keys for a bucket. For more information, see PUT Bucket logging (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlogging.html) +// in the Amazon S3 API Reference. type LoggingEnabled struct { // Specifies the bucket where you want Amazon S3 to store server access logs. You @@ -2360,17 +1788,16 @@ type LoggingEnabled struct { // This member is required. TargetBucket *string - // A prefix for all log object keys. If you store log files from multiple Amazon S3 - // buckets in a single bucket, you can use a prefix to distinguish which log files - // came from which bucket. + // A prefix for all log object keys. If you store log files from multiple Amazon + // S3 buckets in a single bucket, you can use a prefix to distinguish which log + // files came from which bucket. // // This member is required. TargetPrefix *string // Container for granting information. Buckets that use the bucket owner enforced // setting for Object Ownership don't support target grants. For more information, - // see Permissions for server access log delivery - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html#grant-log-delivery-permissions-general) + // see Permissions for server access log delivery (https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html#grant-log-delivery-permissions-general) // in the Amazon S3 User Guide. TargetGrants []TargetGrant @@ -2380,17 +1807,17 @@ type LoggingEnabled struct { // A metadata key-value pair to store with an object. type MetadataEntry struct { - // Name of the Object. + // Name of the object. Name *string - // Value of the Object. + // Value of the object. Value *string noSmithyDocumentSerde } -// A container specifying replication metrics-related settings enabling replication -// metrics and events. +// A container specifying replication metrics-related settings enabling +// replication metrics and events. type Metrics struct { // Specifies whether the replication metrics are enabled. @@ -2405,9 +1832,9 @@ type Metrics struct { noSmithyDocumentSerde } -// A conjunction (logical AND) of predicates, which is used in evaluating a metrics -// filter. The operator must have at least two predicates, and an object must match -// all of the predicates in order for the filter to apply. +// A conjunction (logical AND) of predicates, which is used in evaluating a +// metrics filter. The operator must have at least two predicates, and an object +// must match all of the predicates in order for the filter to apply. type MetricsAndOperator struct { // The access point ARN used when evaluating an AND predicate. @@ -2426,11 +1853,12 @@ type MetricsAndOperator struct { // by the metrics configuration ID) from an Amazon S3 bucket. If you're updating an // existing metrics configuration, note that this is a full replacement of the // existing metrics configuration. If you don't include the elements you want to -// keep, they are erased. For more information, see PutBucketMetricsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTMetricConfiguration.html). +// keep, they are erased. For more information, see PutBucketMetricsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTMetricConfiguration.html) +// . type MetricsConfiguration struct { - // The ID used to identify the metrics configuration. + // The ID used to identify the metrics configuration. The ID has a 64 character + // limit and can only contain letters, numbers, periods, dashes, and underscores. // // This member is required. Id *string @@ -2446,8 +1874,8 @@ type MetricsConfiguration struct { // Specifies a metrics configuration filter. The metrics configuration only // includes objects that meet the filter's criteria. A filter must be a prefix, an // object tag, an access point ARN, or a conjunction (MetricsAndOperator). For more -// information, see PutBucketMetricsConfiguration -// (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html). +// information, see PutBucketMetricsConfiguration (https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html) +// . // // The following types satisfy this interface: // @@ -2468,9 +1896,9 @@ type MetricsFilterMemberAccessPointArn struct { func (*MetricsFilterMemberAccessPointArn) isMetricsFilter() {} -// A conjunction (logical AND) of predicates, which is used in evaluating a metrics -// filter. The operator must have at least two predicates, and an object must match -// all of the predicates in order for the filter to apply. +// A conjunction (logical AND) of predicates, which is used in evaluating a +// metrics filter. The operator must have at least two predicates, and an object +// must match all of the predicates in order for the filter to apply. type MetricsFilterMemberAnd struct { Value MetricsAndOperator @@ -2534,16 +1962,14 @@ type NoncurrentVersionExpiration struct { // Specifies how many noncurrent versions Amazon S3 will retain. If there are this // many more recent noncurrent versions, Amazon S3 will take the associated action. // For more information about noncurrent versions, see Lifecycle configuration - // elements - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/intro-lifecycle-rules.html) + // elements (https://docs.aws.amazon.com/AmazonS3/latest/userguide/intro-lifecycle-rules.html) // in the Amazon S3 User Guide. NewerNoncurrentVersions int32 // Specifies the number of days an object is noncurrent before Amazon S3 can // perform the associated action. The value must be a non-zero positive integer. // For information about the noncurrent days calculations, see How Amazon S3 - // Calculates When an Object Became Noncurrent - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html#non-current-days-calculations) + // Calculates When an Object Became Noncurrent (https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html#non-current-days-calculations) // in the Amazon S3 User Guide. NoncurrentDays int32 @@ -2551,27 +1977,25 @@ type NoncurrentVersionExpiration struct { } // Container for the transition rule that describes when noncurrent objects -// transition to the STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER_IR, -// GLACIER, or DEEP_ARCHIVE storage class. If your bucket is versioning-enabled (or -// versioning is suspended), you can set this action to request that Amazon S3 -// transition noncurrent object versions to the STANDARD_IA, ONEZONE_IA, -// INTELLIGENT_TIERING, GLACIER_IR, GLACIER, or DEEP_ARCHIVE storage class at a +// transition to the STANDARD_IA , ONEZONE_IA , INTELLIGENT_TIERING , GLACIER_IR , +// GLACIER , or DEEP_ARCHIVE storage class. If your bucket is versioning-enabled +// (or versioning is suspended), you can set this action to request that Amazon S3 +// transition noncurrent object versions to the STANDARD_IA , ONEZONE_IA , +// INTELLIGENT_TIERING , GLACIER_IR , GLACIER , or DEEP_ARCHIVE storage class at a // specific period in the object's lifetime. type NoncurrentVersionTransition struct { // Specifies how many noncurrent versions Amazon S3 will retain. If there are this // many more recent noncurrent versions, Amazon S3 will take the associated action. // For more information about noncurrent versions, see Lifecycle configuration - // elements - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/intro-lifecycle-rules.html) + // elements (https://docs.aws.amazon.com/AmazonS3/latest/userguide/intro-lifecycle-rules.html) // in the Amazon S3 User Guide. NewerNoncurrentVersions int32 // Specifies the number of days an object is noncurrent before Amazon S3 can // perform the associated action. For information about the noncurrent days // calculations, see How Amazon S3 Calculates How Long an Object Has Been - // Noncurrent - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html#non-current-days-calculations) + // Noncurrent (https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html#non-current-days-calculations) // in the Amazon S3 User Guide. NoncurrentDays int32 @@ -2581,8 +2005,8 @@ type NoncurrentVersionTransition struct { noSmithyDocumentSerde } -// A container for specifying the notification configuration of the bucket. If this -// element is empty, notifications are turned off for the bucket. +// A container for specifying the notification configuration of the bucket. If +// this element is empty, notifications are turned off for the bucket. type NotificationConfiguration struct { // Enables delivery of events to Amazon EventBridge. @@ -2592,21 +2016,20 @@ type NotificationConfiguration struct { // them. LambdaFunctionConfigurations []LambdaFunctionConfiguration - // The Amazon Simple Queue Service queues to publish messages to and the events for - // which to publish messages. + // The Amazon Simple Queue Service queues to publish messages to and the events + // for which to publish messages. QueueConfigurations []QueueConfiguration - // The topic to which notifications are sent and the events for which notifications - // are generated. + // The topic to which notifications are sent and the events for which + // notifications are generated. TopicConfigurations []TopicConfiguration noSmithyDocumentSerde } // Specifies object key name filtering rules. For information about key name -// filtering, see Configuring Event Notifications -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) in the -// Amazon S3 User Guide. +// filtering, see Configuring event notifications using object key name filtering (https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-filtering.html) +// in the Amazon S3 User Guide. type NotificationConfigurationFilter struct { // A container for object key name prefix and suffix filtering rules. @@ -2625,22 +2048,17 @@ type Object struct { // contents of an object, not its metadata. The ETag may or may not be an MD5 // digest of the object data. Whether or not it is depends on how the object was // created and how it is encrypted as described below: - // - // * Objects created by the - // PUT Object, POST Object, or Copy operation, or through the Amazon Web Services - // Management Console, and are encrypted by SSE-S3 or plaintext, have ETags that - // are an MD5 digest of their object data. - // - // * Objects created by the PUT Object, - // POST Object, or Copy operation, or through the Amazon Web Services Management - // Console, and are encrypted by SSE-C or SSE-KMS, have ETags that are not an MD5 - // digest of their object data. - // - // * If an object is created by either the Multipart - // Upload or Part Copy operation, the ETag is not an MD5 digest, regardless of the - // method of encryption. If an object is larger than 16 MB, the Amazon Web Services - // Management Console will upload or copy that object as a Multipart Upload, and - // therefore the ETag will not be an MD5 digest. + // - Objects created by the PUT Object, POST Object, or Copy operation, or + // through the Amazon Web Services Management Console, and are encrypted by SSE-S3 + // or plaintext, have ETags that are an MD5 digest of their object data. + // - Objects created by the PUT Object, POST Object, or Copy operation, or + // through the Amazon Web Services Management Console, and are encrypted by SSE-C + // or SSE-KMS, have ETags that are not an MD5 digest of their object data. + // - If an object is created by either the Multipart Upload or Part Copy + // operation, the ETag is not an MD5 digest, regardless of the method of + // encryption. If an object is larger than 16 MB, the Amazon Web Services + // Management Console will upload or copy that object as a Multipart Upload, and + // therefore the ETag will not be an MD5 digest. ETag *string // The name that you assign to an object. You use the object key to retrieve the @@ -2653,6 +2071,13 @@ type Object struct { // The owner of the object Owner *Owner + // Specifies the restoration status of an object. Objects in certain storage + // classes must be restored before they can be retrieved. For more information + // about these storage classes and how to work with archived objects, see Working + // with archived objects (https://docs.aws.amazon.com/AmazonS3/latest/userguide/archived-objects.html) + // in the Amazon S3 User Guide. + RestoreStatus *RestoreStatus + // Size in bytes of the object Size int64 @@ -2667,8 +2092,8 @@ type ObjectIdentifier struct { // Key name of the object. Replacement must be made for object keys containing // special characters (such as carriage returns) when using XML requests. For more - // information, see XML related object key constraints - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints). + // information, see XML related object key constraints (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints) + // . // // This member is required. Key *string @@ -2687,9 +2112,9 @@ type ObjectLockConfiguration struct { ObjectLockEnabled ObjectLockEnabled // Specifies the Object Lock rule for the specified object. Enable the this rule - // when you apply ObjectLockConfiguration to a bucket. Bucket settings require both - // a mode and a period. The period can be either Days or Years but you must select - // one. You cannot specify Days and Years at the same time. + // when you apply ObjectLockConfiguration to a bucket. Bucket settings require + // both a mode and a period. The period can be either Days or Years but you must + // select one. You cannot specify Days and Years at the same time. Rule *ObjectLockRule noSmithyDocumentSerde @@ -2734,37 +2159,33 @@ type ObjectPart struct { // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 32-bit CRC32 checksum of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumCRC32 *string // The base64-encoded, 32-bit CRC32C checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32C *string // The base64-encoded, 160-bit SHA-1 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA1 *string // The base64-encoded, 256-bit SHA-256 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA256 *string - // The part number identifying the part. This value is a positive integer between 1 - // and 10,000. + // The part number identifying the part. This value is a positive integer between + // 1 and 10,000. PartNumber int32 // The size of the uploaded part in bytes. @@ -2795,6 +2216,13 @@ type ObjectVersion struct { // Specifies the owner of the object. Owner *Owner + // Specifies the restoration status of an object. Objects in certain storage + // classes must be restored before they can be retrieved. For more information + // about these storage classes and how to work with archived objects, see Working + // with archived objects (https://docs.aws.amazon.com/AmazonS3/latest/userguide/archived-objects.html) + // in the Amazon S3 User Guide. + RestoreStatus *RestoreStatus + // Size in bytes of the object. Size int64 @@ -2831,7 +2259,16 @@ type OutputSerialization struct { // Container for the owner's display name and ID. type Owner struct { - // Container for the display name of the owner. + // Container for the display name of the owner. This value is only supported in + // the following Amazon Web Services Regions: + // - US East (N. Virginia) + // - US West (N. California) + // - US West (Oregon) + // - Asia Pacific (Singapore) + // - Asia Pacific (Sydney) + // - Asia Pacific (Tokyo) + // - Europe (Ireland) + // - South America (São Paulo) DisplayName *string // Container for the ID of the owner. @@ -2883,32 +2320,28 @@ type Part struct { // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 32-bit CRC32 checksum of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumCRC32 *string // The base64-encoded, 32-bit CRC32C checksum of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumCRC32C *string // The base64-encoded, 160-bit SHA-1 digest of the object. This will only be // present if it was uploaded with the object. With multipart uploads, this may not // be a checksum value of the object. For more information about how checksums are - // calculated with multipart uploads, see Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) + // calculated with multipart uploads, see Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#large-object-checksums) // in the Amazon S3 User Guide. ChecksumSHA1 *string // This header can be used as a data integrity check to verify that the data // received is the same data that was originally sent. This header specifies the // base64-encoded, 256-bit SHA-256 digest of the object. For more information, see - // Checking object integrity - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) + // Checking object integrity (https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html) // in the Amazon S3 User Guide. ChecksumSHA256 *string @@ -2965,30 +2398,23 @@ type ProgressEvent struct { // The PublicAccessBlock configuration that you want to apply to this Amazon S3 // bucket. You can enable the configuration options in any combination. For more // information about when Amazon S3 considers a bucket or object public, see The -// Meaning of "Public" -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html#access-control-block-public-access-policy-status) +// Meaning of "Public" (https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html#access-control-block-public-access-policy-status) // in the Amazon S3 User Guide. type PublicAccessBlockConfiguration struct { // Specifies whether Amazon S3 should block public access control lists (ACLs) for // this bucket and objects in this bucket. Setting this element to TRUE causes the // following behavior: - // - // * PUT Bucket ACL and PUT Object ACL calls fail if the - // specified ACL is public. - // - // * PUT Object calls fail if the request includes a - // public ACL. - // - // * PUT Bucket calls fail if the request includes a public - // ACL. - // + // - PUT Bucket ACL and PUT Object ACL calls fail if the specified ACL is + // public. + // - PUT Object calls fail if the request includes a public ACL. + // - PUT Bucket calls fail if the request includes a public ACL. // Enabling this setting doesn't affect existing policies or ACLs. BlockPublicAcls bool - // Specifies whether Amazon S3 should block public bucket policies for this bucket. - // Setting this element to TRUE causes Amazon S3 to reject calls to PUT Bucket - // policy if the specified bucket policy allows public access. Enabling this + // Specifies whether Amazon S3 should block public bucket policies for this + // bucket. Setting this element to TRUE causes Amazon S3 to reject calls to PUT + // Bucket policy if the specified bucket policy allows public access. Enabling this // setting doesn't affect existing bucket policies. BlockPublicPolicy bool @@ -3027,9 +2453,8 @@ type QueueConfiguration struct { QueueArn *string // Specifies object key name filtering rules. For information about key name - // filtering, see Configuring Event Notifications - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) in the - // Amazon S3 User Guide. + // filtering, see Configuring event notifications using object key name filtering (https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-filtering.html) + // in the Amazon S3 User Guide. Filter *NotificationConfigurationFilter // An optional unique identifier for configurations in a notification @@ -3048,8 +2473,8 @@ type RecordsEvent struct { noSmithyDocumentSerde } -// Specifies how requests are redirected. In the event of an error, you can specify -// a different error code to return. +// Specifies how requests are redirected. In the event of an error, you can +// specify a different error code to return. type Redirect struct { // The host name to use in the redirect request. @@ -3065,22 +2490,21 @@ type Redirect struct { // The object key prefix to use in the redirect request. For example, to redirect // requests for all pages with prefix docs/ (objects in the docs/ folder) to - // documents/, you can set a condition block with KeyPrefixEquals set to docs/ and - // in the Redirect set ReplaceKeyPrefixWith to /documents. Not required if one of - // the siblings is present. Can be present only if ReplaceKeyWith is not provided. - // Replacement must be made for object keys containing special characters (such as - // carriage returns) when using XML requests. For more information, see XML - // related object key constraints - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints). + // documents/ , you can set a condition block with KeyPrefixEquals set to docs/ + // and in the Redirect set ReplaceKeyPrefixWith to /documents . Not required if one + // of the siblings is present. Can be present only if ReplaceKeyWith is not + // provided. Replacement must be made for object keys containing special characters + // (such as carriage returns) when using XML requests. For more information, see + // XML related object key constraints (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints) + // . ReplaceKeyPrefixWith *string // The specific object key to use in the redirect request. For example, redirect - // request to error.html. Not required if one of the siblings is present. Can be + // request to error.html . Not required if one of the siblings is present. Can be // present only if ReplaceKeyPrefixWith is not provided. Replacement must be made // for object keys containing special characters (such as carriage returns) when - // using XML requests. For more information, see XML related object key - // constraints - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints). + // using XML requests. For more information, see XML related object key constraints (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints) + // . ReplaceKeyWith *string noSmithyDocumentSerde @@ -3104,11 +2528,11 @@ type RedirectAllRequestsTo struct { // A filter that you can specify for selection for modifications on replicas. // Amazon S3 doesn't replicate replica modifications by default. In the latest -// version of replication configuration (when Filter is specified), you can specify -// this element and set the status to Enabled to replicate modifications on -// replicas. If you don't specify the Filter element, Amazon S3 assumes that the -// replication configuration is the earlier version, V1. In the earlier version, -// this element is not allowed. +// version of replication configuration (when Filter is specified), you can +// specify this element and set the status to Enabled to replicate modifications +// on replicas. If you don't specify the Filter element, Amazon S3 assumes that +// the replication configuration is the earlier version, V1. In the earlier +// version, this element is not allowed. type ReplicaModifications struct { // Specifies whether Amazon S3 replicates modifications on replicas. @@ -3125,9 +2549,8 @@ type ReplicationConfiguration struct { // The Amazon Resource Name (ARN) of the Identity and Access Management (IAM) role // that Amazon S3 assumes when replicating objects. For more information, see How - // to Set Up Replication - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-how-setup.html) in - // the Amazon S3 User Guide. + // to Set Up Replication (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-how-setup.html) + // in the Amazon S3 User Guide. // // This member is required. Role *string @@ -3158,24 +2581,25 @@ type ReplicationRule struct { // Specifies whether Amazon S3 replicates delete markers. If you specify a Filter // in your replication configuration, you must also include a // DeleteMarkerReplication element. If your Filter includes a Tag element, the - // DeleteMarkerReplicationStatus must be set to Disabled, because Amazon S3 does + // DeleteMarkerReplication Status must be set to Disabled, because Amazon S3 does // not support replicating delete markers for tag-based rules. For an example - // configuration, see Basic Rule Configuration - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-add-config.html#replication-config-min-rule-config). - // For more information about delete marker replication, see Basic Rule - // Configuration - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/delete-marker-replication.html). - // If you are using an earlier version of the replication configuration, Amazon S3 - // handles replication of delete markers differently. For more information, see - // Backward Compatibility - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-add-config.html#replication-backward-compat-considerations). + // configuration, see Basic Rule Configuration (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-add-config.html#replication-config-min-rule-config) + // . For more information about delete marker replication, see Basic Rule + // Configuration (https://docs.aws.amazon.com/AmazonS3/latest/dev/delete-marker-replication.html) + // . If you are using an earlier version of the replication configuration, Amazon + // S3 handles replication of delete markers differently. For more information, see + // Backward Compatibility (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-add-config.html#replication-backward-compat-considerations) + // . DeleteMarkerReplication *DeleteMarkerReplication - // + // Optional configuration to replicate existing source bucket objects. For more + // information, see Replicating Existing Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-what-is-isnot-replicated.html#existing-object-replication) + // in the Amazon S3 User Guide. ExistingObjectReplication *ExistingObjectReplication // A filter that identifies the subset of objects to which the replication rule - // applies. A Filter must specify exactly one Prefix, Tag, or an And child element. + // applies. A Filter must specify exactly one Prefix , Tag , or an And child + // element. Filter ReplicationRuleFilter // A unique identifier for the rule. The maximum value is 255 characters. @@ -3185,8 +2609,8 @@ type ReplicationRule struct { // rule applies. The maximum prefix length is 1,024 characters. To include all // objects in a bucket, specify an empty string. Replacement must be made for // object keys containing special characters (such as carriage returns) when using - // XML requests. For more information, see XML related object key constraints - // (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints). + // XML requests. For more information, see XML related object key constraints (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints) + // . // // Deprecated: This member has been deprecated. Prefix *string @@ -3196,16 +2620,15 @@ type ReplicationRule struct { // according to all replication rules. However, if there are two or more rules with // the same destination bucket, then objects will be replicated according to the // rule with the highest priority. The higher the number, the higher the priority. - // For more information, see Replication - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication.html) in the Amazon - // S3 User Guide. + // For more information, see Replication (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication.html) + // in the Amazon S3 User Guide. Priority int32 - // A container that describes additional filters for identifying the source objects - // that you want to replicate. You can choose to enable or disable the replication - // of these objects. Currently, Amazon S3 supports only the filter that you can - // specify for objects created with server-side encryption using a customer managed - // key stored in Amazon Web Services Key Management Service (SSE-KMS). + // A container that describes additional filters for identifying the source + // objects that you want to replicate. You can choose to enable or disable the + // replication of these objects. Currently, Amazon S3 supports only the filter that + // you can specify for objects created with server-side encryption using a customer + // managed key stored in Amazon Web Services Key Management Service (SSE-KMS). SourceSelectionCriteria *SourceSelectionCriteria noSmithyDocumentSerde @@ -3214,12 +2637,10 @@ type ReplicationRule struct { // A container for specifying rule filters. The filters determine the subset of // objects to which the rule applies. This element is required only if you specify // more than one filter. For example: -// -// * If you specify both a Prefix and a Tag -// filter, wrap these filters in an And tag. -// -// * If you specify a filter based on -// multiple tags, wrap the Tag elements in an And tag. +// - If you specify both a Prefix and a Tag filter, wrap these filters in an And +// tag. +// - If you specify a filter based on multiple tags, wrap the Tag elements in an +// And tag. type ReplicationRuleAndOperator struct { // An object key name prefix that identifies the subset of objects to which the @@ -3233,7 +2654,8 @@ type ReplicationRuleAndOperator struct { } // A filter that identifies the subset of objects to which the replication rule -// applies. A Filter must specify exactly one Prefix, Tag, or an And child element. +// applies. A Filter must specify exactly one Prefix , Tag , or an And child +// element. // // The following types satisfy this interface: // @@ -3247,12 +2669,10 @@ type ReplicationRuleFilter interface { // A container for specifying rule filters. The filters determine the subset of // objects to which the rule applies. This element is required only if you specify // more than one filter. For example: -// -// * If you specify both a Prefix and a Tag -// filter, wrap these filters in an And tag. -// -// * If you specify a filter based on -// multiple tags, wrap the Tag elements in an And tag. +// - If you specify both a Prefix and a Tag filter, wrap these filters in an And +// tag. +// - If you specify a filter based on multiple tags, wrap the Tag elements in an +// And tag. type ReplicationRuleFilterMemberAnd struct { Value ReplicationRuleAndOperator @@ -3264,8 +2684,8 @@ func (*ReplicationRuleFilterMemberAnd) isReplicationRuleFilter() {} // An object key name prefix that identifies the subset of objects to which the // rule applies. Replacement must be made for object keys containing special // characters (such as carriage returns) when using XML requests. For more -// information, see XML related object key constraints -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints). +// information, see XML related object key constraints (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints) +// . type ReplicationRuleFilterMemberPrefix struct { Value string @@ -3274,8 +2694,8 @@ type ReplicationRuleFilterMemberPrefix struct { func (*ReplicationRuleFilterMemberPrefix) isReplicationRuleFilter() {} -// A container for specifying a tag key and value. The rule applies only to objects -// that have the tag in their tag set. +// A container for specifying a tag key and value. The rule applies only to +// objects that have the tag in their tag set. type ReplicationRuleFilterMemberTag struct { Value Tag @@ -3284,9 +2704,10 @@ type ReplicationRuleFilterMemberTag struct { func (*ReplicationRuleFilterMemberTag) isReplicationRuleFilter() {} -// A container specifying S3 Replication Time Control (S3 RTC) related information, -// including whether S3 RTC is enabled and the time when all objects and operations -// on objects must be replicated. Must be specified together with a Metrics block. +// A container specifying S3 Replication Time Control (S3 RTC) related +// information, including whether S3 RTC is enabled and the time when all objects +// and operations on objects must be replicated. Must be specified together with a +// Metrics block. type ReplicationTime struct { // Specifies whether the replication time is enabled. @@ -3304,7 +2725,7 @@ type ReplicationTime struct { } // A container specifying the time value for S3 Replication Time Control (S3 RTC) -// and replication metrics EventThreshold. +// and replication metrics EventThreshold . type ReplicationTimeValue struct { // Contains an integer specifying time in minutes. Valid value: 15 @@ -3338,7 +2759,7 @@ type RequestProgress struct { type RestoreRequest struct { // Lifetime of the active copy in days. Do not use with restores that specify - // OutputLocation. The Days element is required for regular restores, and must not + // OutputLocation . The Days element is required for regular restores, and must not // be provided for select requests. Days int32 @@ -3346,7 +2767,7 @@ type RestoreRequest struct { Description *string // S3 Glacier related parameters pertaining to this job. Do not use with restores - // that specify OutputLocation. + // that specify OutputLocation . GlacierJobParameters *GlacierJobParameters // Describes the location where the restore job's output is stored. @@ -3364,9 +2785,33 @@ type RestoreRequest struct { noSmithyDocumentSerde } +// Specifies the restoration status of an object. Objects in certain storage +// classes must be restored before they can be retrieved. For more information +// about these storage classes and how to work with archived objects, see Working +// with archived objects (https://docs.aws.amazon.com/AmazonS3/latest/userguide/archived-objects.html) +// in the Amazon S3 User Guide. +type RestoreStatus struct { + + // Specifies whether the object is currently being restored. If the object + // restoration is in progress, the header returns the value TRUE . For example: + // x-amz-optional-object-attributes: IsRestoreInProgress="true" If the object + // restoration has completed, the header returns the value FALSE . For example: + // x-amz-optional-object-attributes: IsRestoreInProgress="false", + // RestoreExpiryDate="2012-12-21T00:00:00.000Z" If the object hasn't been restored, + // there is no header response. + IsRestoreInProgress bool + + // Indicates when the restored copy will expire. This value is populated only if + // the object has already been restored. For example: + // x-amz-optional-object-attributes: IsRestoreInProgress="false", + // RestoreExpiryDate="2012-12-21T00:00:00.000Z" + RestoreExpiryDate *time.Time + + noSmithyDocumentSerde +} + // Specifies the redirect behavior and when a redirect is applied. For more -// information about routing rules, see Configuring advanced conditional redirects -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html#advanced-conditional-redirects) +// information about routing rules, see Configuring advanced conditional redirects (https://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html#advanced-conditional-redirects) // in the Amazon S3 User Guide. type RoutingRule struct { @@ -3443,10 +2888,10 @@ type ScanRange struct { // scan the last N bytes of the file. For example, 50 means scan the last 50 bytes. End int64 - // Specifies the start of the byte range. This parameter is optional. Valid values: - // non-negative integers. The default value is 0. If only start is supplied, it - // means scan from that point to the end of the file. For example, 50 means scan - // from byte 50 until the end of the file. + // Specifies the start of the byte range. This parameter is optional. Valid + // values: non-negative integers. The default value is 0. If only start is + // supplied, it means scan from that point to the end of the file. For example, 50 + // means scan from byte 50 until the end of the file. Start int64 noSmithyDocumentSerde @@ -3542,8 +2987,7 @@ type SelectParameters struct { // at configuration, Amazon S3 automatically creates an Amazon Web Services KMS key // in your Amazon Web Services account the first time that you add an object // encrypted with SSE-KMS to a bucket. By default, Amazon S3 uses this KMS key for -// SSE-KMS. For more information, see PUT Bucket encryption -// (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTencryption.html) +// SSE-KMS. For more information, see PUT Bucket encryption (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTencryption.html) // in the Amazon S3 API Reference. type ServerSideEncryptionByDefault struct { @@ -3554,23 +2998,18 @@ type ServerSideEncryptionByDefault struct { // Amazon Web Services Key Management Service (KMS) customer Amazon Web Services // KMS key ID to use for the default encryption. This parameter is allowed if and - // only if SSEAlgorithm is set to aws:kms. You can specify the key ID or the Amazon - // Resource Name (ARN) of the KMS key. However, if you are using encryption with - // cross-account or Amazon Web Services service operations you must use a fully - // qualified KMS key ARN. For more information, see Using encryption for - // cross-account operations - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html#bucket-encryption-update-bucket-policy). - // For example: - // - // * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab - // - // * Key ARN: - // arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab - // - // Amazon - // S3 only supports symmetric KMS keys and not asymmetric KMS keys. For more - // information, see Using symmetric and asymmetric keys - // (https://docs.aws.amazon.com/kms/latest/developerguide/symmetric-asymmetric.html) + // only if SSEAlgorithm is set to aws:kms . You can specify the key ID, key alias, + // or the Amazon Resource Name (ARN) of the KMS key. + // - Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab + // - Key ARN: + // arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab + // - Key Alias: alias/alias-name + // If you use a key ID, you can run into a LogDestination undeliverable error when + // creating a VPC flow log. If you are using encryption with cross-account or + // Amazon Web Services service operations you must use a fully qualified KMS key + // ARN. For more information, see Using encryption for cross-account operations (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html#bucket-encryption-update-bucket-policy) + // . Amazon S3 only supports symmetric encryption KMS keys. For more information, + // see Asymmetric keys in Amazon Web Services KMS (https://docs.aws.amazon.com/kms/latest/developerguide/symmetric-asymmetric.html) // in the Amazon Web Services Key Management Service Developer Guide. KMSMasterKeyID *string @@ -3601,28 +3040,27 @@ type ServerSideEncryptionRule struct { // encryption using KMS (SSE-KMS) for new objects in the bucket. Existing objects // are not affected. Setting the BucketKeyEnabled element to true causes Amazon S3 // to use an S3 Bucket Key. By default, S3 Bucket Key is not enabled. For more - // information, see Amazon S3 Bucket Keys - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html) in the Amazon - // S3 User Guide. + // information, see Amazon S3 Bucket Keys (https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html) + // in the Amazon S3 User Guide. BucketKeyEnabled bool noSmithyDocumentSerde } -// A container that describes additional filters for identifying the source objects -// that you want to replicate. You can choose to enable or disable the replication -// of these objects. Currently, Amazon S3 supports only the filter that you can -// specify for objects created with server-side encryption using a customer managed -// key stored in Amazon Web Services Key Management Service (SSE-KMS). +// A container that describes additional filters for identifying the source +// objects that you want to replicate. You can choose to enable or disable the +// replication of these objects. Currently, Amazon S3 supports only the filter that +// you can specify for objects created with server-side encryption using a customer +// managed key stored in Amazon Web Services Key Management Service (SSE-KMS). type SourceSelectionCriteria struct { // A filter that you can specify for selections for modifications on replicas. // Amazon S3 doesn't replicate replica modifications by default. In the latest - // version of replication configuration (when Filter is specified), you can specify - // this element and set the status to Enabled to replicate modifications on - // replicas. If you don't specify the Filter element, Amazon S3 assumes that the - // replication configuration is the earlier version, V1. In the earlier version, - // this element is not allowed + // version of replication configuration (when Filter is specified), you can + // specify this element and set the status to Enabled to replicate modifications + // on replicas. If you don't specify the Filter element, Amazon S3 assumes that + // the replication configuration is the earlier version, V1. In the earlier + // version, this element is not allowed ReplicaModifications *ReplicaModifications // A container for filter information for the selection of Amazon S3 objects @@ -3636,9 +3074,8 @@ type SourceSelectionCriteria struct { // Specifies the use of SSE-KMS to encrypt delivered inventory reports. type SSEKMS struct { - // Specifies the ID of the Amazon Web Services Key Management Service (Amazon Web - // Services KMS) symmetric customer managed key to use for encrypting inventory - // reports. + // Specifies the ID of the Key Management Service (KMS) symmetric encryption + // customer managed key to use for encrypting inventory reports. // // This member is required. KeyId *string @@ -3693,15 +3130,15 @@ type StatsEvent struct { // analyze the tradeoffs between different storage classes for an Amazon S3 bucket. type StorageClassAnalysis struct { - // Specifies how data related to the storage class analysis for an Amazon S3 bucket - // should be exported. + // Specifies how data related to the storage class analysis for an Amazon S3 + // bucket should be exported. DataExport *StorageClassAnalysisDataExport noSmithyDocumentSerde } -// Container for data related to the storage class analysis for an Amazon S3 bucket -// for export. +// Container for data related to the storage class analysis for an Amazon S3 +// bucket for export. type StorageClassAnalysisDataExport struct { // The place to store the data for an analysis. @@ -3709,7 +3146,7 @@ type StorageClassAnalysisDataExport struct { // This member is required. Destination *AnalyticsExportDestination - // The version of the output schema to use when exporting data. Must be V_1. + // The version of the output schema to use when exporting data. Must be V_1 . // // This member is required. OutputSchemaVersion StorageClassAnalysisSchemaVersion @@ -3746,8 +3183,7 @@ type Tagging struct { // Container for granting information. Buckets that use the bucket owner enforced // setting for Object Ownership don't support target grants. For more information, -// see Permissions server access log delivery -// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html#grant-log-delivery-permissions-general) +// see Permissions server access log delivery (https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html#grant-log-delivery-permissions-general) // in the Amazon S3 User Guide. type TargetGrant struct { @@ -3766,8 +3202,7 @@ type TargetGrant struct { type Tiering struct { // S3 Intelligent-Tiering access tier. See Storage class for automatically - // optimizing frequently and infrequently accessed objects - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access) + // optimizing frequently and infrequently accessed objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access) // for a list of access tiers in the S3 Intelligent-Tiering storage class. // // This member is required. @@ -3791,9 +3226,8 @@ type Tiering struct { type TopicConfiguration struct { // The Amazon S3 bucket event about which to send notifications. For more - // information, see Supported Event Types - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) in the - // Amazon S3 User Guide. + // information, see Supported Event Types (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) + // in the Amazon S3 User Guide. // // This member is required. Events []Event @@ -3805,9 +3239,8 @@ type TopicConfiguration struct { TopicArn *string // Specifies object key name filtering rules. For information about key name - // filtering, see Configuring Event Notifications - // (https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) in the - // Amazon S3 User Guide. + // filtering, see Configuring event notifications using object key name filtering (https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-filtering.html) + // in the Amazon S3 User Guide. Filter *NotificationConfigurationFilter // An optional unique identifier for configurations in a notification @@ -3819,17 +3252,16 @@ type TopicConfiguration struct { // Specifies when an object transitions to a specified storage class. For more // information about Amazon S3 lifecycle configuration rules, see Transitioning -// Objects Using Amazon S3 Lifecycle -// (https://docs.aws.amazon.com/AmazonS3/latest/dev/lifecycle-transition-general-considerations.html) +// Objects Using Amazon S3 Lifecycle (https://docs.aws.amazon.com/AmazonS3/latest/dev/lifecycle-transition-general-considerations.html) // in the Amazon S3 User Guide. type Transition struct { - // Indicates when objects are transitioned to the specified storage class. The date - // value must be in ISO 8601 format. The time is always midnight UTC. + // Indicates when objects are transitioned to the specified storage class. The + // date value must be in ISO 8601 format. The time is always midnight UTC. Date *time.Time - // Indicates the number of days after creation when objects are transitioned to the - // specified storage class. The value must be a positive integer. + // Indicates the number of days after creation when objects are transitioned to + // the specified storage class. The value must be a positive integer. Days int32 // The storage class to which you want the object to transition. @@ -3838,9 +3270,8 @@ type Transition struct { noSmithyDocumentSerde } -// Describes the versioning state of an Amazon S3 bucket. For more information, see -// PUT Bucket versioning -// (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTVersioningStatus.html) +// Describes the versioning state of an Amazon S3 bucket. For more information, +// see PUT Bucket versioning (https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTVersioningStatus.html) // in the Amazon S3 API Reference. type VersioningConfiguration struct { 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 index 42fae8efb..0b2700161 100644 --- 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 @@ -1,3 +1,61 @@ +# 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. 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 index 6f30ddc99..da4e470a6 100644 --- 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 @@ -4,6 +4,7 @@ package sso import ( "context" + "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" @@ -45,8 +46,6 @@ func New(options Options, optFns ...func(*Options)) *Client { resolveHTTPSignerV4(&options) - resolveDefaultEndpointConfiguration(&options) - for _, fn := range optFns { fn(&options) } @@ -64,6 +63,14 @@ type Options struct { // 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 @@ -78,8 +85,18 @@ type Options struct { 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. This should be used over + // the deprecated EndpointResolver + EndpointResolverV2 EndpointResolverV2 + // Signature Version 4 (SigV4) Signer HTTPSignerV4 HTTPSignerV4 @@ -138,14 +155,25 @@ func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { } } -// WithEndpointResolver returns a functional option for setting the Client's -// EndpointResolver option. +// 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 + } +} + type HTTPClient interface { Do(*http.Request) (*http.Response, error) } @@ -162,6 +190,8 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf ctx = middleware.ClearStackValues(ctx) stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) options := c.options.Copy() + resolveEndpointResolverV2(&options) + for _, fn := range optFns { fn(&options) } @@ -196,6 +226,30 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf 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 @@ -233,6 +287,7 @@ func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { APIOptions: cfg.APIOptions, Logger: cfg.Logger, ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) @@ -343,11 +398,19 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil { return } - o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions, NewDefaultEndpointResolver()) + o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) } -func addClientUserAgent(stack *middleware.Stack) error { - return awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "sso", goModuleVersion)(stack) +func addClientUserAgent(stack *middleware.Stack, options Options) error { + if err := awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "sso", goModuleVersion)(stack); err != nil { + return err + } + + if len(options.AppID) > 0 { + return awsmiddleware.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID)(stack) + } + + return nil } func addHTTPSignerV4Middleware(stack *middleware.Stack, o Options) error { @@ -431,3 +494,32 @@ func addRequestResponseLogging(stack *middleware.Stack, o Options) error { LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), }, middleware.After) } + +type endpointDisableHTTPSMiddleware struct { + EndpointDisableHTTPS bool +} + +func (*endpointDisableHTTPSMiddleware) ID() string { + return "endpointDisableHTTPSMiddleware" +} + +func (m *endpointDisableHTTPSMiddleware) 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) + } + + if m.EndpointDisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) { + req.URL.Scheme = "http" + } + + return next.HandleSerialize(ctx, in) + +} +func addendpointDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { + return stack.Serialize.Insert(&endpointDisableHTTPSMiddleware{ + EndpointDisableHTTPS: o.EndpointOptions.DisableHTTPS, + }, "OperationSerializer", middleware.Before) +} 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 index 3825b9e44..0383bb0bd 100644 --- 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 @@ -4,8 +4,13 @@ package sso import ( "context" + "errors" + "fmt" + "github.com/aws/aws-sdk-go-v2/aws" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/sso/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -69,6 +74,9 @@ func (c *Client) addOperationGetRoleCredentialsMiddlewares(stack *middleware.Sta if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -90,7 +98,7 @@ func (c *Client) addOperationGetRoleCredentialsMiddlewares(stack *middleware.Sta if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -99,6 +107,9 @@ func (c *Client) addOperationGetRoleCredentialsMiddlewares(stack *middleware.Sta if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetRoleCredentialsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetRoleCredentialsValidationMiddleware(stack); err != nil { return err } @@ -117,6 +128,9 @@ func (c *Client) addOperationGetRoleCredentialsMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -127,3 +141,126 @@ func newServiceMetadataMiddleware_opGetRoleCredentials(region string) *awsmiddle OperationName: "GetRoleCredentials", } } + +type opGetRoleCredentialsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetRoleCredentialsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetRoleCredentialsResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "awsssoportal" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "awsssoportal" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("awsssoportal") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetRoleCredentialsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetRoleCredentialsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index ef3592afc..cc28543f8 100644 --- 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 @@ -4,9 +4,13 @@ package sso import ( "context" + "errors" "fmt" + "github.com/aws/aws-sdk-go-v2/aws" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/sso/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -75,6 +79,9 @@ func (c *Client) addOperationListAccountRolesMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -96,7 +103,7 @@ func (c *Client) addOperationListAccountRolesMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -105,6 +112,9 @@ func (c *Client) addOperationListAccountRolesMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addListAccountRolesResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpListAccountRolesValidationMiddleware(stack); err != nil { return err } @@ -123,6 +133,9 @@ func (c *Client) addOperationListAccountRolesMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -223,3 +236,126 @@ func newServiceMetadataMiddleware_opListAccountRoles(region string) *awsmiddlewa OperationName: "ListAccountRoles", } } + +type opListAccountRolesResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListAccountRolesResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListAccountRolesResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "awsssoportal" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "awsssoportal" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("awsssoportal") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListAccountRolesResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListAccountRolesResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index cfa8cdc97..567f6c669 100644 --- 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 @@ -4,9 +4,13 @@ package sso import ( "context" + "errors" "fmt" + "github.com/aws/aws-sdk-go-v2/aws" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/sso/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -73,6 +77,9 @@ func (c *Client) addOperationListAccountsMiddlewares(stack *middleware.Stack, op if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -94,7 +101,7 @@ func (c *Client) addOperationListAccountsMiddlewares(stack *middleware.Stack, op if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -103,6 +110,9 @@ func (c *Client) addOperationListAccountsMiddlewares(stack *middleware.Stack, op if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addListAccountsResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpListAccountsValidationMiddleware(stack); err != nil { return err } @@ -121,6 +131,9 @@ func (c *Client) addOperationListAccountsMiddlewares(stack *middleware.Stack, op if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -220,3 +233,126 @@ func newServiceMetadataMiddleware_opListAccounts(region string) *awsmiddleware.R OperationName: "ListAccounts", } } + +type opListAccountsResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opListAccountsResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opListAccountsResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "awsssoportal" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "awsssoportal" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("awsssoportal") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addListAccountsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opListAccountsResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index c13d73f5a..c30da0296 100644 --- 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 @@ -4,7 +4,12 @@ package sso import ( "context" + "errors" + "fmt" + "github.com/aws/aws-sdk-go-v2/aws" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -64,6 +69,9 @@ func (c *Client) addOperationLogoutMiddlewares(stack *middleware.Stack, options if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -85,7 +93,7 @@ func (c *Client) addOperationLogoutMiddlewares(stack *middleware.Stack, options if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -94,6 +102,9 @@ func (c *Client) addOperationLogoutMiddlewares(stack *middleware.Stack, options if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addLogoutResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpLogoutValidationMiddleware(stack); err != nil { return err } @@ -112,6 +123,9 @@ func (c *Client) addOperationLogoutMiddlewares(stack *middleware.Stack, options if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -122,3 +136,126 @@ func newServiceMetadataMiddleware_opLogout(region string) *awsmiddleware.Registe OperationName: "Logout", } } + +type opLogoutResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opLogoutResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opLogoutResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "awsssoportal" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "awsssoportal" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("awsssoportal") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addLogoutResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opLogoutResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index 43c06f11a..6a2c7eb3e 100644 --- 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 @@ -8,9 +8,13 @@ import ( "fmt" "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/endpoints/awsrulesfn" internalendpoints "github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" smithyhttp "github.com/aws/smithy-go/transport/http" + "net/http" "net/url" "strings" ) @@ -39,13 +43,6 @@ func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointRe return fn(region, options) } -func resolveDefaultEndpointConfiguration(o *Options) { - if o.EndpointResolver != nil { - return - } - o.EndpointResolver = NewDefaultEndpointResolver() -} - // 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 @@ -79,6 +76,10 @@ func (*ResolveEndpoint) ID() string { 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) @@ -94,6 +95,11 @@ func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.Ser 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) } @@ -129,27 +135,10 @@ func removeResolveEndpointMiddleware(stack *middleware.Stack) error { type wrappedEndpointResolver struct { awsResolver aws.EndpointResolverWithOptions - resolver EndpointResolver } func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - if w.awsResolver == nil { - goto fallback - } - endpoint, err = w.awsResolver.ResolveEndpoint(ServiceID, region, options) - if err == nil { - return endpoint, nil - } - - if nf := (&aws.EndpointNotFoundError{}); !errors.As(err, &nf) { - return endpoint, err - } - -fallback: - if w.resolver == nil { - return endpoint, fmt.Errorf("default endpoint resolver provided was nil") - } - return w.resolver.ResolveEndpoint(region, options) + return w.awsResolver.ResolveEndpoint(ServiceID, region, options) } type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error) @@ -160,12 +149,13 @@ func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, opti var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil) -// withEndpointResolver returns an EndpointResolver that first delegates endpoint resolution to the awsResolver. -// If awsResolver returns aws.EndpointNotFoundError error, the resolver will use the the provided -// fallbackResolver for resolution. +// 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. // -// fallbackResolver must not be nil -func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions, fallbackResolver EndpointResolver) EndpointResolver { +// 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 { @@ -176,7 +166,6 @@ func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptio return &wrappedEndpointResolver{ awsResolver: resolver, - resolver: fallbackResolver, } } @@ -198,3 +187,313 @@ func finalizeClientEndpointResolverOptions(options *Options) { } } + +func resolveEndpointResolverV2(options *Options) { + if options.EndpointResolverV2 == nil { + options.EndpointResolverV2 = NewDefaultEndpointResolverV2() + } +} + +// Utility function to aid with translating pseudo-regions to classical regions +// with the appropriate setting indicated by the pseudo-region +func mapPseudoRegion(pr string) (region string, fips aws.FIPSEndpointState) { + const fipsInfix = "-fips-" + const fipsPrefix = "fips-" + const fipsSuffix = "-fips" + + if strings.Contains(pr, fipsInfix) || + strings.Contains(pr, fipsPrefix) || + strings.Contains(pr, fipsSuffix) { + region = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll( + pr, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "") + fips = aws.FIPSEndpointStateEnabled + } else { + region = pr + } + + return region, fips +} + +// builtInParameterResolver is the interface responsible for resolving BuiltIn +// values during the sourcing of EndpointParameters +type builtInParameterResolver interface { + ResolveBuiltIns(*EndpointParameters) error +} + +// builtInResolver resolves modeled BuiltIn values using only the members defined +// below. +type builtInResolver struct { + // The AWS region used to dispatch the request. + Region string + + // Sourced BuiltIn value in a historical enabled or disabled state. + UseDualStack aws.DualStackEndpointState + + // Sourced BuiltIn value in a historical enabled or disabled state. + UseFIPS aws.FIPSEndpointState + + // Base endpoint that can potentially be modified during Endpoint resolution. + Endpoint *string +} + +// Invoked at runtime to resolve BuiltIn Values. Only resolution code specific to +// each BuiltIn value is generated. +func (b *builtInResolver) ResolveBuiltIns(params *EndpointParameters) error { + + region, _ := mapPseudoRegion(b.Region) + if len(region) == 0 { + return fmt.Errorf("Could not resolve AWS::Region") + } else { + params.Region = aws.String(region) + } + if b.UseDualStack == aws.DualStackEndpointStateEnabled { + params.UseDualStack = aws.Bool(true) + } else { + params.UseDualStack = aws.Bool(false) + } + if b.UseFIPS == aws.FIPSEndpointStateEnabled { + params.UseFIPS = aws.Bool(true) + } else { + params.UseFIPS = aws.Bool(false) + } + params.Endpoint = b.Endpoint + return 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 +} + +// 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 +} + +// 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") +} 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 index 5be0e34cd..ab6af36e8 100644 --- 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 @@ -3,7 +3,8 @@ "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" + "github.com/aws/smithy-go": "v1.4.0", + "github.com/google/go-cmp": "v0.5.4" }, "files": [ "api_client.go", @@ -15,6 +16,7 @@ "deserializers.go", "doc.go", "endpoints.go", + "endpoints_test.go", "generated.json", "internal/endpoints/endpoints.go", "internal/endpoints/endpoints_test.go", 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 index b67186c86..0f216f4ef 100644 --- 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 @@ -3,4 +3,4 @@ package sso // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.12.12" +const goModuleVersion = "1.15.2" 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 index b1ce03a5d..f044afde4 100644 --- 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 @@ -94,7 +94,7 @@ var partitionRegexp = struct { AwsUsGov *regexp.Regexp }{ - Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af)\\-\\w+\\-\\d+$"), + Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il)\\-\\w+\\-\\d+$"), AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"), AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"), AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"), @@ -227,6 +227,14 @@ var defaultPartitions = endpoints.Partitions{ 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{ @@ -267,6 +275,14 @@ var defaultPartitions = endpoints.Partitions{ 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-south-1", }: endpoints.Endpoint{ @@ -351,6 +367,24 @@ var defaultPartitions = endpoints.Partitions{ }, 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", 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 index 29e320811..02e314115 100644 --- 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 @@ -36,7 +36,14 @@ func (m *awsRestjson1_serializeOpGetRoleCredentials) HandleSerialize(ctx context request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -98,7 +105,14 @@ func (m *awsRestjson1_serializeOpListAccountRoles) HandleSerialize(ctx context.C request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -164,7 +178,14 @@ func (m *awsRestjson1_serializeOpListAccounts) HandleSerialize(ctx context.Conte request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "GET" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -226,7 +247,14 @@ func (m *awsRestjson1_serializeOpLogout) HandleSerialize(ctx context.Context, in request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "POST" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } 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 index c6c01750b..536619724 100644 --- 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 @@ -1,3 +1,61 @@ +# 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. 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 index 111f66d3b..24a692276 100644 --- 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 @@ -4,6 +4,7 @@ package ssooidc import ( "context" + "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" @@ -45,8 +46,6 @@ func New(options Options, optFns ...func(*Options)) *Client { resolveHTTPSignerV4(&options) - resolveDefaultEndpointConfiguration(&options) - for _, fn := range optFns { fn(&options) } @@ -64,6 +63,14 @@ type Options struct { // 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 @@ -78,8 +85,18 @@ type Options struct { 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. This should be used over + // the deprecated EndpointResolver + EndpointResolverV2 EndpointResolverV2 + // Signature Version 4 (SigV4) Signer HTTPSignerV4 HTTPSignerV4 @@ -138,14 +155,25 @@ func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { } } -// WithEndpointResolver returns a functional option for setting the Client's -// EndpointResolver option. +// 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 + } +} + type HTTPClient interface { Do(*http.Request) (*http.Response, error) } @@ -162,6 +190,8 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf ctx = middleware.ClearStackValues(ctx) stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) options := c.options.Copy() + resolveEndpointResolverV2(&options) + for _, fn := range optFns { fn(&options) } @@ -196,6 +226,30 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf 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 @@ -233,6 +287,7 @@ func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { APIOptions: cfg.APIOptions, Logger: cfg.Logger, ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) @@ -343,11 +398,19 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil { return } - o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions, NewDefaultEndpointResolver()) + o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) } -func addClientUserAgent(stack *middleware.Stack) error { - return awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "ssooidc", goModuleVersion)(stack) +func addClientUserAgent(stack *middleware.Stack, options Options) error { + if err := awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "ssooidc", goModuleVersion)(stack); err != nil { + return err + } + + if len(options.AppID) > 0 { + return awsmiddleware.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID)(stack) + } + + return nil } func addHTTPSignerV4Middleware(stack *middleware.Stack, o Options) error { @@ -431,3 +494,32 @@ func addRequestResponseLogging(stack *middleware.Stack, o Options) error { LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), }, middleware.After) } + +type endpointDisableHTTPSMiddleware struct { + EndpointDisableHTTPS bool +} + +func (*endpointDisableHTTPSMiddleware) ID() string { + return "endpointDisableHTTPSMiddleware" +} + +func (m *endpointDisableHTTPSMiddleware) 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) + } + + if m.EndpointDisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) { + req.URL.Scheme = "http" + } + + return next.HandleSerialize(ctx, in) + +} +func addendpointDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { + return stack.Serialize.Insert(&endpointDisableHTTPSMiddleware{ + EndpointDisableHTTPS: o.EndpointOptions.DisableHTTPS, + }, "OperationSerializer", middleware.Before) +} 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 index 5d7bd3c1f..43df6256c 100644 --- 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 @@ -4,7 +4,12 @@ package ssooidc import ( "context" + "errors" + "fmt" + "github.com/aws/aws-sdk-go-v2/aws" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -119,6 +124,9 @@ func (c *Client) addOperationCreateTokenMiddlewares(stack *middleware.Stack, opt if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -140,7 +148,7 @@ func (c *Client) addOperationCreateTokenMiddlewares(stack *middleware.Stack, opt if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -149,6 +157,9 @@ func (c *Client) addOperationCreateTokenMiddlewares(stack *middleware.Stack, opt if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addCreateTokenResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpCreateTokenValidationMiddleware(stack); err != nil { return err } @@ -167,6 +178,9 @@ func (c *Client) addOperationCreateTokenMiddlewares(stack *middleware.Stack, opt if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -177,3 +191,126 @@ func newServiceMetadataMiddleware_opCreateToken(region string) *awsmiddleware.Re OperationName: "CreateToken", } } + +type opCreateTokenResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opCreateTokenResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opCreateTokenResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "awsssooidc" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "awsssooidc" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("awsssooidc") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addCreateTokenResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opCreateTokenResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index 1d83b226d..b88ebb706 100644 --- 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 @@ -4,7 +4,12 @@ package ssooidc import ( "context" + "errors" + "fmt" + "github.com/aws/aws-sdk-go-v2/aws" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -84,6 +89,9 @@ func (c *Client) addOperationRegisterClientMiddlewares(stack *middleware.Stack, if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -105,7 +113,7 @@ func (c *Client) addOperationRegisterClientMiddlewares(stack *middleware.Stack, if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -114,6 +122,9 @@ func (c *Client) addOperationRegisterClientMiddlewares(stack *middleware.Stack, if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addRegisterClientResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpRegisterClientValidationMiddleware(stack); err != nil { return err } @@ -132,6 +143,9 @@ func (c *Client) addOperationRegisterClientMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -142,3 +156,126 @@ func newServiceMetadataMiddleware_opRegisterClient(region string) *awsmiddleware OperationName: "RegisterClient", } } + +type opRegisterClientResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opRegisterClientResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opRegisterClientResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "awsssooidc" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "awsssooidc" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("awsssooidc") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addRegisterClientResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opRegisterClientResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index 70e60db14..327da5f73 100644 --- 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 @@ -4,7 +4,12 @@ package ssooidc import ( "context" + "errors" + "fmt" + "github.com/aws/aws-sdk-go-v2/aws" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -92,6 +97,9 @@ func (c *Client) addOperationStartDeviceAuthorizationMiddlewares(stack *middlewa if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -113,7 +121,7 @@ func (c *Client) addOperationStartDeviceAuthorizationMiddlewares(stack *middlewa if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -122,6 +130,9 @@ func (c *Client) addOperationStartDeviceAuthorizationMiddlewares(stack *middlewa if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addStartDeviceAuthorizationResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpStartDeviceAuthorizationValidationMiddleware(stack); err != nil { return err } @@ -140,6 +151,9 @@ func (c *Client) addOperationStartDeviceAuthorizationMiddlewares(stack *middlewa if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -150,3 +164,126 @@ func newServiceMetadataMiddleware_opStartDeviceAuthorization(region string) *aws OperationName: "StartDeviceAuthorization", } } + +type opStartDeviceAuthorizationResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opStartDeviceAuthorizationResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opStartDeviceAuthorizationResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "awsssooidc" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "awsssooidc" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("awsssooidc") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addStartDeviceAuthorizationResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opStartDeviceAuthorizationResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index 35cd21f18..e8d190e48 100644 --- 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 @@ -8,9 +8,13 @@ import ( "fmt" "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/endpoints/awsrulesfn" internalendpoints "github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" smithyhttp "github.com/aws/smithy-go/transport/http" + "net/http" "net/url" "strings" ) @@ -39,13 +43,6 @@ func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointRe return fn(region, options) } -func resolveDefaultEndpointConfiguration(o *Options) { - if o.EndpointResolver != nil { - return - } - o.EndpointResolver = NewDefaultEndpointResolver() -} - // 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 @@ -79,6 +76,10 @@ func (*ResolveEndpoint) ID() string { 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) @@ -94,6 +95,11 @@ func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.Ser 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) } @@ -129,27 +135,10 @@ func removeResolveEndpointMiddleware(stack *middleware.Stack) error { type wrappedEndpointResolver struct { awsResolver aws.EndpointResolverWithOptions - resolver EndpointResolver } func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - if w.awsResolver == nil { - goto fallback - } - endpoint, err = w.awsResolver.ResolveEndpoint(ServiceID, region, options) - if err == nil { - return endpoint, nil - } - - if nf := (&aws.EndpointNotFoundError{}); !errors.As(err, &nf) { - return endpoint, err - } - -fallback: - if w.resolver == nil { - return endpoint, fmt.Errorf("default endpoint resolver provided was nil") - } - return w.resolver.ResolveEndpoint(region, options) + return w.awsResolver.ResolveEndpoint(ServiceID, region, options) } type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error) @@ -160,12 +149,13 @@ func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, opti var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil) -// withEndpointResolver returns an EndpointResolver that first delegates endpoint resolution to the awsResolver. -// If awsResolver returns aws.EndpointNotFoundError error, the resolver will use the the provided -// fallbackResolver for resolution. +// 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. // -// fallbackResolver must not be nil -func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions, fallbackResolver EndpointResolver) EndpointResolver { +// 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 { @@ -176,7 +166,6 @@ func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptio return &wrappedEndpointResolver{ awsResolver: resolver, - resolver: fallbackResolver, } } @@ -198,3 +187,313 @@ func finalizeClientEndpointResolverOptions(options *Options) { } } + +func resolveEndpointResolverV2(options *Options) { + if options.EndpointResolverV2 == nil { + options.EndpointResolverV2 = NewDefaultEndpointResolverV2() + } +} + +// Utility function to aid with translating pseudo-regions to classical regions +// with the appropriate setting indicated by the pseudo-region +func mapPseudoRegion(pr string) (region string, fips aws.FIPSEndpointState) { + const fipsInfix = "-fips-" + const fipsPrefix = "fips-" + const fipsSuffix = "-fips" + + if strings.Contains(pr, fipsInfix) || + strings.Contains(pr, fipsPrefix) || + strings.Contains(pr, fipsSuffix) { + region = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll( + pr, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "") + fips = aws.FIPSEndpointStateEnabled + } else { + region = pr + } + + return region, fips +} + +// builtInParameterResolver is the interface responsible for resolving BuiltIn +// values during the sourcing of EndpointParameters +type builtInParameterResolver interface { + ResolveBuiltIns(*EndpointParameters) error +} + +// builtInResolver resolves modeled BuiltIn values using only the members defined +// below. +type builtInResolver struct { + // The AWS region used to dispatch the request. + Region string + + // Sourced BuiltIn value in a historical enabled or disabled state. + UseDualStack aws.DualStackEndpointState + + // Sourced BuiltIn value in a historical enabled or disabled state. + UseFIPS aws.FIPSEndpointState + + // Base endpoint that can potentially be modified during Endpoint resolution. + Endpoint *string +} + +// Invoked at runtime to resolve BuiltIn Values. Only resolution code specific to +// each BuiltIn value is generated. +func (b *builtInResolver) ResolveBuiltIns(params *EndpointParameters) error { + + region, _ := mapPseudoRegion(b.Region) + if len(region) == 0 { + return fmt.Errorf("Could not resolve AWS::Region") + } else { + params.Region = aws.String(region) + } + if b.UseDualStack == aws.DualStackEndpointStateEnabled { + params.UseDualStack = aws.Bool(true) + } else { + params.UseDualStack = aws.Bool(false) + } + if b.UseFIPS == aws.FIPSEndpointStateEnabled { + params.UseFIPS = aws.Bool(true) + } else { + params.UseFIPS = aws.Bool(false) + } + params.Endpoint = b.Endpoint + return 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 +} + +// 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 +} + +// 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 true == _PartitionResult.SupportsFIPS { + if "aws-us-gov" == _PartitionResult.Name { + 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") +} 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 index 4afe3223e..fe2d075ad 100644 --- 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 @@ -3,7 +3,8 @@ "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" + "github.com/aws/smithy-go": "v1.4.0", + "github.com/google/go-cmp": "v0.5.4" }, "files": [ "api_client.go", @@ -14,6 +15,7 @@ "deserializers.go", "doc.go", "endpoints.go", + "endpoints_test.go", "generated.json", "internal/endpoints/endpoints.go", "internal/endpoints/endpoints_test.go", 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 index 82156c20f..fab953b91 100644 --- 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 @@ -3,4 +3,4 @@ package ssooidc // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.14.12" +const goModuleVersion = "1.17.3" 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 index b04fb46fe..c48da8b88 100644 --- 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 @@ -94,7 +94,7 @@ var partitionRegexp = struct { AwsUsGov *regexp.Regexp }{ - Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af)\\-\\w+\\-\\d+$"), + Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il)\\-\\w+\\-\\d+$"), AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"), AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"), AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"), @@ -227,6 +227,14 @@ var defaultPartitions = endpoints.Partitions{ 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{ @@ -267,6 +275,14 @@ var defaultPartitions = endpoints.Partitions{ 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-south-1", }: endpoints.Endpoint{ @@ -351,6 +367,24 @@ var defaultPartitions = endpoints.Partitions{ }, 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", 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 index a8cfd7b46..efca8b250 100644 --- 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 @@ -38,7 +38,14 @@ func (m *awsRestjson1_serializeOpCreateToken) HandleSerialize(ctx context.Contex request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "POST" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -143,7 +150,14 @@ func (m *awsRestjson1_serializeOpRegisterClient) HandleSerialize(ctx context.Con request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "POST" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } @@ -223,7 +237,14 @@ func (m *awsRestjson1_serializeOpStartDeviceAuthorization) HandleSerialize(ctx c request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) request.Method = "POST" - restEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + 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} } 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 index 46a30e5b7..d94dc1ab3 100644 --- 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 @@ -1,3 +1,57 @@ +# 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. 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 index 78eb26702..22ac69043 100644 --- 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 @@ -4,6 +4,7 @@ package sts import ( "context" + "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" @@ -48,8 +49,6 @@ func New(options Options, optFns ...func(*Options)) *Client { resolveHTTPSignerV4(&options) - resolveDefaultEndpointConfiguration(&options) - for _, fn := range optFns { fn(&options) } @@ -67,6 +66,14 @@ type Options struct { // 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 @@ -81,8 +88,18 @@ type Options struct { 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. This should be used over + // the deprecated EndpointResolver + EndpointResolverV2 EndpointResolverV2 + // Signature Version 4 (SigV4) Signer HTTPSignerV4 HTTPSignerV4 @@ -141,14 +158,25 @@ func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { } } -// WithEndpointResolver returns a functional option for setting the Client's -// EndpointResolver option. +// 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 + } +} + type HTTPClient interface { Do(*http.Request) (*http.Response, error) } @@ -165,6 +193,8 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf ctx = middleware.ClearStackValues(ctx) stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) options := c.options.Copy() + resolveEndpointResolverV2(&options) + for _, fn := range optFns { fn(&options) } @@ -199,6 +229,30 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf 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 @@ -236,6 +290,7 @@ func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { APIOptions: cfg.APIOptions, Logger: cfg.Logger, ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) @@ -346,11 +401,19 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil { return } - o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions, NewDefaultEndpointResolver()) + o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) } -func addClientUserAgent(stack *middleware.Stack) error { - return awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "sts", goModuleVersion)(stack) +func addClientUserAgent(stack *middleware.Stack, options Options) error { + if err := awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "sts", goModuleVersion)(stack); err != nil { + return err + } + + if len(options.AppID) > 0 { + return awsmiddleware.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID)(stack) + } + + return nil } func addHTTPSignerV4Middleware(stack *middleware.Stack, o Options) error { @@ -535,3 +598,32 @@ func addRequestResponseLogging(stack *middleware.Stack, o Options) error { LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), }, middleware.After) } + +type endpointDisableHTTPSMiddleware struct { + EndpointDisableHTTPS bool +} + +func (*endpointDisableHTTPSMiddleware) ID() string { + return "endpointDisableHTTPSMiddleware" +} + +func (m *endpointDisableHTTPSMiddleware) 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) + } + + if m.EndpointDisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) { + req.URL.Scheme = "http" + } + + return next.HandleSerialize(ctx, in) + +} +func addendpointDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { + return stack.Serialize.Insert(&endpointDisableHTTPSMiddleware{ + EndpointDisableHTTPS: o.EndpointOptions.DisableHTTPS, + }, "OperationSerializer", 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 index db22efc0e..0ef7affc5 100644 --- 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 @@ -4,9 +4,14 @@ package sts import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/sts/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -199,6 +204,9 @@ type AssumeRoleInput struct { // in the IAM User Guide. PolicyArns []types.PolicyDescriptorType + // Reserved for future use. + 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. @@ -327,6 +335,9 @@ func (c *Client) addOperationAssumeRoleMiddlewares(stack *middleware.Stack, opti if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -354,7 +365,7 @@ func (c *Client) addOperationAssumeRoleMiddlewares(stack *middleware.Stack, opti if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -363,6 +374,9 @@ func (c *Client) addOperationAssumeRoleMiddlewares(stack *middleware.Stack, opti if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addAssumeRoleResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpAssumeRoleValidationMiddleware(stack); err != nil { return err } @@ -381,6 +395,9 @@ func (c *Client) addOperationAssumeRoleMiddlewares(stack *middleware.Stack, opti if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -416,3 +433,126 @@ func (c *PresignClient) PresignAssumeRole(ctx context.Context, params *AssumeRol out := result.(*v4.PresignedHTTPRequest) return out, nil } + +type opAssumeRoleResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opAssumeRoleResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opAssumeRoleResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "sts" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "sts" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("sts") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addAssumeRoleResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opAssumeRoleResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index 65dccc9ea..9c33720d4 100644 --- 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 @@ -4,8 +4,13 @@ package sts import ( "context" + "errors" + "fmt" + "github.com/aws/aws-sdk-go-v2/aws" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/sts/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -284,6 +289,9 @@ func (c *Client) addOperationAssumeRoleWithSAMLMiddlewares(stack *middleware.Sta if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -305,7 +313,7 @@ func (c *Client) addOperationAssumeRoleWithSAMLMiddlewares(stack *middleware.Sta if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -314,6 +322,9 @@ func (c *Client) addOperationAssumeRoleWithSAMLMiddlewares(stack *middleware.Sta if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addAssumeRoleWithSAMLResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpAssumeRoleWithSAMLValidationMiddleware(stack); err != nil { return err } @@ -332,6 +343,9 @@ func (c *Client) addOperationAssumeRoleWithSAMLMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -343,3 +357,126 @@ func newServiceMetadataMiddleware_opAssumeRoleWithSAML(region string) *awsmiddle OperationName: "AssumeRoleWithSAML", } } + +type opAssumeRoleWithSAMLResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opAssumeRoleWithSAMLResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opAssumeRoleWithSAMLResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "sts" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "sts" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("sts") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addAssumeRoleWithSAMLResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opAssumeRoleWithSAMLResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index f00f30763..fa4a60845 100644 --- 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 @@ -4,8 +4,13 @@ package sts import ( "context" + "errors" + "fmt" + "github.com/aws/aws-sdk-go-v2/aws" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/sts/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -149,7 +154,8 @@ type AssumeRoleWithWebIdentityInput struct { // 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. + // application makes an AssumeRoleWithWebIdentity call. Only tokens with RSA + // algorithms (RS256) are supported. // // This member is required. WebIdentityToken *string @@ -302,6 +308,9 @@ func (c *Client) addOperationAssumeRoleWithWebIdentityMiddlewares(stack *middlew if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -323,7 +332,7 @@ func (c *Client) addOperationAssumeRoleWithWebIdentityMiddlewares(stack *middlew if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -332,6 +341,9 @@ func (c *Client) addOperationAssumeRoleWithWebIdentityMiddlewares(stack *middlew if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addAssumeRoleWithWebIdentityResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpAssumeRoleWithWebIdentityValidationMiddleware(stack); err != nil { return err } @@ -350,6 +362,9 @@ func (c *Client) addOperationAssumeRoleWithWebIdentityMiddlewares(stack *middlew if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -361,3 +376,126 @@ func newServiceMetadataMiddleware_opAssumeRoleWithWebIdentity(region string) *aw OperationName: "AssumeRoleWithWebIdentity", } } + +type opAssumeRoleWithWebIdentityResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opAssumeRoleWithWebIdentityResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opAssumeRoleWithWebIdentityResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "sts" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "sts" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("sts") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addAssumeRoleWithWebIdentityResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opAssumeRoleWithWebIdentityResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index 587d1d3c0..baf2f9686 100644 --- 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 @@ -4,8 +4,13 @@ package sts import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -81,6 +86,9 @@ func (c *Client) addOperationDecodeAuthorizationMessageMiddlewares(stack *middle if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -108,7 +116,7 @@ func (c *Client) addOperationDecodeAuthorizationMessageMiddlewares(stack *middle if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -117,6 +125,9 @@ func (c *Client) addOperationDecodeAuthorizationMessageMiddlewares(stack *middle if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addDecodeAuthorizationMessageResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpDecodeAuthorizationMessageValidationMiddleware(stack); err != nil { return err } @@ -135,6 +146,9 @@ func (c *Client) addOperationDecodeAuthorizationMessageMiddlewares(stack *middle if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -146,3 +160,126 @@ func newServiceMetadataMiddleware_opDecodeAuthorizationMessage(region string) *a OperationName: "DecodeAuthorizationMessage", } } + +type opDecodeAuthorizationMessageResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opDecodeAuthorizationMessageResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opDecodeAuthorizationMessageResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "sts" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "sts" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("sts") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addDecodeAuthorizationMessageResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opDecodeAuthorizationMessageResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index f090ecf47..f1dd167da 100644 --- 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 @@ -4,8 +4,13 @@ package sts import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -74,6 +79,9 @@ func (c *Client) addOperationGetAccessKeyInfoMiddlewares(stack *middleware.Stack if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -101,7 +109,7 @@ func (c *Client) addOperationGetAccessKeyInfoMiddlewares(stack *middleware.Stack if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -110,6 +118,9 @@ func (c *Client) addOperationGetAccessKeyInfoMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetAccessKeyInfoResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetAccessKeyInfoValidationMiddleware(stack); err != nil { return err } @@ -128,6 +139,9 @@ func (c *Client) addOperationGetAccessKeyInfoMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -139,3 +153,126 @@ func newServiceMetadataMiddleware_opGetAccessKeyInfo(region string) *awsmiddlewa OperationName: "GetAccessKeyInfo", } } + +type opGetAccessKeyInfoResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetAccessKeyInfoResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetAccessKeyInfoResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "sts" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "sts" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("sts") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetAccessKeyInfoResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetAccessKeyInfoResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index 93823927b..66e5d99d4 100644 --- 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 @@ -4,8 +4,13 @@ package sts import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -69,6 +74,9 @@ func (c *Client) addOperationGetCallerIdentityMiddlewares(stack *middleware.Stac if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -96,7 +104,7 @@ func (c *Client) addOperationGetCallerIdentityMiddlewares(stack *middleware.Stac if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -105,6 +113,9 @@ func (c *Client) addOperationGetCallerIdentityMiddlewares(stack *middleware.Stac if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetCallerIdentityResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetCallerIdentity(options.Region), middleware.Before); err != nil { return err } @@ -120,6 +131,9 @@ func (c *Client) addOperationGetCallerIdentityMiddlewares(stack *middleware.Stac if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -155,3 +169,126 @@ func (c *PresignClient) PresignGetCallerIdentity(ctx context.Context, params *Ge out := result.(*v4.PresignedHTTPRequest) return out, nil } + +type opGetCallerIdentityResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetCallerIdentityResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetCallerIdentityResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "sts" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "sts" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("sts") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetCallerIdentityResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetCallerIdentityResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index ccb7366e2..d577ef686 100644 --- 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 @@ -4,9 +4,14 @@ package sts import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/sts/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -241,6 +246,9 @@ func (c *Client) addOperationGetFederationTokenMiddlewares(stack *middleware.Sta if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -268,7 +276,7 @@ func (c *Client) addOperationGetFederationTokenMiddlewares(stack *middleware.Sta if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -277,6 +285,9 @@ func (c *Client) addOperationGetFederationTokenMiddlewares(stack *middleware.Sta if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetFederationTokenResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = addOpGetFederationTokenValidationMiddleware(stack); err != nil { return err } @@ -295,6 +306,9 @@ func (c *Client) addOperationGetFederationTokenMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -306,3 +320,126 @@ func newServiceMetadataMiddleware_opGetFederationToken(region string) *awsmiddle OperationName: "GetFederationToken", } } + +type opGetFederationTokenResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetFederationTokenResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetFederationTokenResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "sts" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "sts" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("sts") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetFederationTokenResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetFederationTokenResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index 4dfac4c98..7a2345e80 100644 --- 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 @@ -4,9 +4,14 @@ package sts import ( "context" + "errors" + "fmt" + "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/aws/signer/v4" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" "github.com/aws/aws-sdk-go-v2/service/sts/types" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -127,6 +132,9 @@ func (c *Client) addOperationGetSessionTokenMiddlewares(stack *middleware.Stack, if err != nil { return err } + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } if err = addSetLoggerMiddleware(stack, options); err != nil { return err } @@ -154,7 +162,7 @@ func (c *Client) addOperationGetSessionTokenMiddlewares(stack *middleware.Stack, if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -163,6 +171,9 @@ func (c *Client) addOperationGetSessionTokenMiddlewares(stack *middleware.Stack, if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addGetSessionTokenResolveEndpointMiddleware(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetSessionToken(options.Region), middleware.Before); err != nil { return err } @@ -178,6 +189,9 @@ func (c *Client) addOperationGetSessionTokenMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -189,3 +203,126 @@ func newServiceMetadataMiddleware_opGetSessionToken(region string) *awsmiddlewar OperationName: "GetSessionToken", } } + +type opGetSessionTokenResolveEndpointMiddleware struct { + EndpointResolver EndpointResolverV2 + BuiltInResolver builtInParameterResolver +} + +func (*opGetSessionTokenResolveEndpointMiddleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *opGetSessionTokenResolveEndpointMiddleware) 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.EndpointResolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := EndpointParameters{} + + m.BuiltInResolver.ResolveBuiltIns(¶ms) + + var resolvedEndpoint smithyendpoints.Endpoint + resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL = &resolvedEndpoint.URI + + for k := range resolvedEndpoint.Headers { + req.Header.Set( + k, + resolvedEndpoint.Headers.Get(k), + ) + } + + authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties) + if err != nil { + var nfe *internalauth.NoAuthenticationSchemesFoundError + if errors.As(err, &nfe) { + // if no auth scheme is found, default to sigv4 + signingName := "sts" + signingRegion := m.BuiltInResolver.(*builtInResolver).Region + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + + } + var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError + if errors.As(err, &ue) { + return out, metadata, fmt.Errorf( + "This operation requests signer version(s) %v but the client only supports %v", + ue.UnsupportedSchemes, + internalauth.SupportedSchemes, + ) + } + } + + for _, authScheme := range authSchemes { + switch authScheme.(type) { + case *internalauth.AuthenticationSchemeV4: + v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4) + var signingName, signingRegion string + if v4Scheme.SigningName == nil { + signingName = "sts" + } else { + signingName = *v4Scheme.SigningName + } + if v4Scheme.SigningRegion == nil { + signingRegion = m.BuiltInResolver.(*builtInResolver).Region + } else { + signingRegion = *v4Scheme.SigningRegion + } + if v4Scheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion) + break + case *internalauth.AuthenticationSchemeV4A: + v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A) + if v4aScheme.SigningName == nil { + v4aScheme.SigningName = aws.String("sts") + } + if v4aScheme.DisableDoubleEncoding != nil { + // The signer sets an equivalent value at client initialization time. + // Setting this context value will cause the signer to extract it + // and override the value set at client initialization time. + ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding) + } + ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName) + ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0]) + break + case *internalauth.AuthenticationSchemeNone: + break + } + } + + return next.HandleSerialize(ctx, in) +} + +func addGetSessionTokenResolveEndpointMiddleware(stack *middleware.Stack, options Options) error { + return stack.Serialize.Insert(&opGetSessionTokenResolveEndpointMiddleware{ + EndpointResolver: options.EndpointResolverV2, + BuiltInResolver: &builtInResolver{ + Region: options.Region, + UseDualStack: options.EndpointOptions.UseDualStackEndpoint, + UseFIPS: options.EndpointOptions.UseFIPSEndpoint, + Endpoint: options.BaseEndpoint, + }, + }, "ResolveEndpoint", middleware.After) +} 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 index cababea22..ef1caae8d 100644 --- 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 @@ -8,9 +8,14 @@ import ( "fmt" "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/endpoints/awsrulesfn" internalendpoints "github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints" + smithy "github.com/aws/smithy-go" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" smithyhttp "github.com/aws/smithy-go/transport/http" + "net/http" "net/url" "strings" ) @@ -39,13 +44,6 @@ func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointRe return fn(region, options) } -func resolveDefaultEndpointConfiguration(o *Options) { - if o.EndpointResolver != nil { - return - } - o.EndpointResolver = NewDefaultEndpointResolver() -} - // 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 @@ -79,6 +77,10 @@ func (*ResolveEndpoint) ID() string { 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) @@ -94,6 +96,11 @@ func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.Ser 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) } @@ -129,27 +136,10 @@ func removeResolveEndpointMiddleware(stack *middleware.Stack) error { type wrappedEndpointResolver struct { awsResolver aws.EndpointResolverWithOptions - resolver EndpointResolver } func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - if w.awsResolver == nil { - goto fallback - } - endpoint, err = w.awsResolver.ResolveEndpoint(ServiceID, region, options) - if err == nil { - return endpoint, nil - } - - if nf := (&aws.EndpointNotFoundError{}); !errors.As(err, &nf) { - return endpoint, err - } - -fallback: - if w.resolver == nil { - return endpoint, fmt.Errorf("default endpoint resolver provided was nil") - } - return w.resolver.ResolveEndpoint(region, options) + return w.awsResolver.ResolveEndpoint(ServiceID, region, options) } type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error) @@ -160,12 +150,13 @@ func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, opti var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil) -// withEndpointResolver returns an EndpointResolver that first delegates endpoint resolution to the awsResolver. -// If awsResolver returns aws.EndpointNotFoundError error, the resolver will use the the provided -// fallbackResolver for resolution. +// 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. // -// fallbackResolver must not be nil -func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions, fallbackResolver EndpointResolver) EndpointResolver { +// 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 { @@ -176,7 +167,6 @@ func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptio return &wrappedEndpointResolver{ awsResolver: resolver, - resolver: fallbackResolver, } } @@ -198,3 +188,789 @@ func finalizeClientEndpointResolverOptions(options *Options) { } } + +func resolveEndpointResolverV2(options *Options) { + if options.EndpointResolverV2 == nil { + options.EndpointResolverV2 = NewDefaultEndpointResolverV2() + } +} + +// Utility function to aid with translating pseudo-regions to classical regions +// with the appropriate setting indicated by the pseudo-region +func mapPseudoRegion(pr string) (region string, fips aws.FIPSEndpointState) { + const fipsInfix = "-fips-" + const fipsPrefix = "fips-" + const fipsSuffix = "-fips" + + if strings.Contains(pr, fipsInfix) || + strings.Contains(pr, fipsPrefix) || + strings.Contains(pr, fipsSuffix) { + region = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll( + pr, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "") + fips = aws.FIPSEndpointStateEnabled + } else { + region = pr + } + + return region, fips +} + +// builtInParameterResolver is the interface responsible for resolving BuiltIn +// values during the sourcing of EndpointParameters +type builtInParameterResolver interface { + ResolveBuiltIns(*EndpointParameters) error +} + +// builtInResolver resolves modeled BuiltIn values using only the members defined +// below. +type builtInResolver struct { + // The AWS region used to dispatch the request. + Region string + + // Sourced BuiltIn value in a historical enabled or disabled state. + UseDualStack aws.DualStackEndpointState + + // Sourced BuiltIn value in a historical enabled or disabled state. + UseFIPS aws.FIPSEndpointState + + // Base endpoint that can potentially be modified during Endpoint resolution. + Endpoint *string + + // Whether the global endpoint should be used, rather then the regional endpoint + // for us-east-1. + UseGlobalEndpoint bool +} + +// Invoked at runtime to resolve BuiltIn Values. Only resolution code specific to +// each BuiltIn value is generated. +func (b *builtInResolver) ResolveBuiltIns(params *EndpointParameters) error { + + region, _ := mapPseudoRegion(b.Region) + if len(region) == 0 { + return fmt.Errorf("Could not resolve AWS::Region") + } else { + params.Region = aws.String(region) + } + if b.UseDualStack == aws.DualStackEndpointStateEnabled { + params.UseDualStack = aws.Bool(true) + } else { + params.UseDualStack = aws.Bool(false) + } + if b.UseFIPS == aws.FIPSEndpointStateEnabled { + params.UseFIPS = aws.Bool(true) + } else { + params.UseFIPS = aws.Bool(false) + } + params.Endpoint = b.Endpoint + params.UseGlobalEndpoint = aws.Bool(b.UseGlobalEndpoint) + return 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 +} + +// 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 + _UseGlobalEndpoint := *params.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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": _Region, + }, + }) + 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 true == _PartitionResult.SupportsFIPS { + if "aws-us-gov" == _PartitionResult.Name { + 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 + out.Set("authSchemes", []interface{}{ + map[string]interface{}{ + "name": "sigv4", + "signingName": "sts", + "signingRegion": "us-east-1", + }, + }) + 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") +} 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 index 86341bb7d..2ae7a9b23 100644 --- 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 @@ -4,7 +4,8 @@ "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/presigned-url": "v1.0.7", - "github.com/aws/smithy-go": "v1.4.0" + "github.com/aws/smithy-go": "v1.4.0", + "github.com/google/go-cmp": "v0.5.4" }, "files": [ "api_client.go", @@ -20,6 +21,7 @@ "deserializers.go", "doc.go", "endpoints.go", + "endpoints_test.go", "generated.json", "internal/endpoints/endpoints.go", "internal/endpoints/endpoints_test.go", 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 index f88dca99c..90dc95f1e 100644 --- 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 @@ -3,4 +3,4 @@ package sts // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.19.2" +const goModuleVersion = "1.23.2" 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 index 0413fd89a..ca4c88190 100644 --- 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 @@ -94,7 +94,7 @@ var partitionRegexp = struct { AwsUsGov *regexp.Regexp }{ - Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af)\\-\\w+\\-\\d+$"), + Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il)\\-\\w+\\-\\d+$"), AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"), AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"), AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"), @@ -207,6 +207,9 @@ var defaultPartitions = endpoints.Partitions{ endpoints.EndpointKey{ Region: "eu-west-3", }: endpoints.Endpoint{}, + endpoints.EndpointKey{ + Region: "il-central-1", + }: endpoints.Endpoint{}, endpoints.EndpointKey{ Region: "me-central-1", }: endpoints.Endpoint{}, 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 index eb60f61b1..4c08061c0 100644 --- 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 @@ -546,6 +546,35 @@ func awsAwsquery_serializeDocumentPolicyDescriptorType(v *types.PolicyDescriptor 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 @@ -611,6 +640,13 @@ func awsAwsquery_serializeOpDocumentAssumeRoleInput(v *AssumeRoleInput, value qu } } + 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) 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 index 90d4f62ae..572a70512 100644 --- 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 @@ -89,6 +89,18 @@ type PolicyDescriptorType struct { noSmithyDocumentSerde } +// Reserved for future use. +type ProvidedContext struct { + + // Reserved for future use. + ContextAssertion *string + + // Reserved for future use. + 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 diff --git a/vendor/github.com/aws/smithy-go/.gitignore b/vendor/github.com/aws/smithy-go/.gitignore index c01141aa4..c92d6105e 100644 --- a/vendor/github.com/aws/smithy-go/.gitignore +++ b/vendor/github.com/aws/smithy-go/.gitignore @@ -20,3 +20,7 @@ target/ build/ */out/ */*/out/ + +# VS Code +bin/ +.vscode/ diff --git a/vendor/github.com/aws/smithy-go/CHANGELOG.md b/vendor/github.com/aws/smithy-go/CHANGELOG.md index 1e23bf95b..8a3540e04 100644 --- a/vendor/github.com/aws/smithy-go/CHANGELOG.md +++ b/vendor/github.com/aws/smithy-go/CHANGELOG.md @@ -1,3 +1,24 @@ +# 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. diff --git a/vendor/github.com/aws/smithy-go/README.md b/vendor/github.com/aws/smithy-go/README.md index a4bb43fbe..c374f6928 100644 --- a/vendor/github.com/aws/smithy-go/README.md +++ b/vendor/github.com/aws/smithy-go/README.md @@ -6,6 +6,21 @@ **WARNING: All interfaces are subject to change.** +## Can I use this? + +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, +therefore the useability of this project on its own is currently limited. +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. + ## License This project is licensed under the Apache-2.0 License. diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go index 96abd073a..543e7cf03 100644 --- a/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go +++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go @@ -26,10 +26,17 @@ type Encoder struct { header http.Header } -// NewEncoder creates a new encoder from the passed in request. All query and +// 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 NewEncoder(path, query string, headers http.Header) (*Encoder, error) { +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) @@ -37,7 +44,7 @@ func NewEncoder(path, query string, headers http.Header) (*Encoder, error) { e := &Encoder{ path: []byte(path), - rawPath: []byte(path), + rawPath: []byte(rawPath), query: parseQuery, header: headers.Clone(), } diff --git a/vendor/github.com/aws/smithy-go/endpoints/endpoint.go b/vendor/github.com/aws/smithy-go/endpoints/endpoint.go new file mode 100644 index 000000000..a93528397 --- /dev/null +++ b/vendor/github.com/aws/smithy-go/endpoints/endpoint.go @@ -0,0 +1,23 @@ +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 specfiying 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 new file mode 100644 index 000000000..e24e190dc --- /dev/null +++ b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/doc.go @@ -0,0 +1,4 @@ +// 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 new file mode 100644 index 000000000..8e230783e --- /dev/null +++ b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/strings.go @@ -0,0 +1,26 @@ +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 new file mode 100644 index 000000000..0c1154127 --- /dev/null +++ b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go @@ -0,0 +1,130 @@ +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/go_module_metadata.go b/vendor/github.com/aws/smithy-go/go_module_metadata.go index 8eaac41e7..6b795a2c8 100644 --- a/vendor/github.com/aws/smithy-go/go_module_metadata.go +++ b/vendor/github.com/aws/smithy-go/go_module_metadata.go @@ -3,4 +3,4 @@ package smithy // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.13.5" +const goModuleVersion = "1.15.0" diff --git a/vendor/github.com/aws/smithy-go/properties.go b/vendor/github.com/aws/smithy-go/properties.go new file mode 100644 index 000000000..17d659c53 --- /dev/null +++ b/vendor/github.com/aws/smithy-go/properties.go @@ -0,0 +1,52 @@ +package smithy + +// PropertiesReader provides an interface for reading metadata from the +// underlying metadata container. +type PropertiesReader interface { + Get(key interface{}) interface{} +} + +// Properties 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. +// +// Properties 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 Properties 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 *Properties) Get(key interface{}) interface{} { + 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. +// +// 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 *Properties) 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 *Properties) 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/transport/http/middleware_header_comment.go b/vendor/github.com/aws/smithy-go/transport/http/middleware_header_comment.go new file mode 100644 index 000000000..855c22720 --- /dev/null +++ b/vendor/github.com/aws/smithy-go/transport/http/middleware_header_comment.go @@ -0,0 +1,81 @@ +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/awslabs/amazon-ecr-credential-helper/ecr-login/api/client.go b/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api/client.go index 2289ef6d9..02ed9762d 100644 --- a/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api/client.go +++ b/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api/client.go @@ -25,7 +25,6 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/ecr" "github.com/aws/aws-sdk-go-v2/service/ecrpublic" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cache" @@ -227,7 +226,7 @@ func (c *defaultClient) getAuthorizationToken(registryID string) (*Auth, error) err = fmt.Errorf("missing AuthorizationData in ECR response for %s", registryID) } } - return nil, errors.Wrap(err, "ecr: Failed to get authorization token") + return nil, fmt.Errorf("ecr: Failed to get authorization token: %w", err) } for _, authData := range output.AuthorizationData { @@ -262,7 +261,7 @@ func (c *defaultClient) getPublicAuthorizationToken() (*Auth, error) { output, err := c.ecrPublicClient.GetAuthorizationToken(context.TODO(), input) if err != nil { - return nil, errors.Wrap(err, "ecr: failed to get authorization token") + return nil, fmt.Errorf("ecr: failed to get authorization token: %w", err) } if output == nil || output.AuthorizationData == nil { return nil, fmt.Errorf("ecr: missing AuthorizationData in ECR Public response") @@ -286,7 +285,7 @@ func (c *defaultClient) getPublicAuthorizationToken() (*Auth, error) { func extractToken(token string, proxyEndpoint string) (*Auth, error) { decodedToken, err := base64.StdEncoding.DecodeString(token) if err != nil { - return nil, errors.Wrap(err, "invalid token") + return nil, fmt.Errorf("invalid token: %w", err) } parts := strings.SplitN(string(decodedToken), ":", 2) diff --git a/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cache/file.go b/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cache/file.go index bc70693b8..19dc33bb5 100644 --- a/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cache/file.go +++ b/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cache/file.go @@ -16,7 +16,6 @@ package cache import ( "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" @@ -123,7 +122,7 @@ func (f *fileCredentialCache) fullFilePath() string { // This eliminates from reading partially written credential files, and reduces (but does not eliminate) concurrent // file access. There is not guarantee here for handling multiple writes at once since there is no out of process locking. func (f *fileCredentialCache) save(registryCache *RegistryCache) error { - file, err := ioutil.TempFile(f.path, ".config.json.tmp") + file, err := os.CreateTemp(f.path, ".config.json.tmp") if err != nil { return err } diff --git a/vendor/github.com/buildkite/agent/v3/api/annotations.go b/vendor/github.com/buildkite/agent/v3/api/annotations.go index 31c7e9bea..8bb086882 100644 --- a/vendor/github.com/buildkite/agent/v3/api/annotations.go +++ b/vendor/github.com/buildkite/agent/v3/api/annotations.go @@ -15,7 +15,7 @@ type Annotation struct { // Annotate a build in the Buildkite UI func (c *Client) Annotate(ctx context.Context, jobId string, annotation *Annotation) (*Response, error) { - u := fmt.Sprintf("jobs/%s/annotations", jobId) + u := fmt.Sprintf("jobs/%s/annotations", railsPathEscape(jobId)) req, err := c.newRequest(ctx, "POST", u, annotation) if err != nil { @@ -27,7 +27,7 @@ func (c *Client) Annotate(ctx context.Context, jobId string, annotation *Annotat // Remove an annotation from a build func (c *Client) AnnotationRemove(ctx context.Context, jobId string, context string) (*Response, error) { - u := fmt.Sprintf("jobs/%s/annotations/%s", jobId, context) + u := fmt.Sprintf("jobs/%s/annotations/%s", railsPathEscape(jobId), railsPathEscape(context)) req, err := c.newRequest(ctx, "DELETE", u, nil) if err != nil { diff --git a/vendor/github.com/buildkite/agent/v3/api/artifacts.go b/vendor/github.com/buildkite/agent/v3/api/artifacts.go index df2a84f86..ffd9749ed 100644 --- a/vendor/github.com/buildkite/agent/v3/api/artifacts.go +++ b/vendor/github.com/buildkite/agent/v3/api/artifacts.go @@ -93,7 +93,7 @@ type ArtifactBatchUpdateRequest struct { // CreateArtifacts takes a slice of artifacts, and creates them on Buildkite as a batch. func (c *Client) CreateArtifacts(ctx context.Context, jobId string, batch *ArtifactBatch) (*ArtifactBatchCreateResponse, *Response, error) { - u := fmt.Sprintf("jobs/%s/artifacts", jobId) + u := fmt.Sprintf("jobs/%s/artifacts", railsPathEscape(jobId)) req, err := c.newRequest(ctx, "POST", u, batch) if err != nil { @@ -111,7 +111,7 @@ func (c *Client) CreateArtifacts(ctx context.Context, jobId string, batch *Artif // Updates a particular artifact func (c *Client) UpdateArtifacts(ctx context.Context, jobId string, artifactStates map[string]string) (*Response, error) { - u := fmt.Sprintf("jobs/%s/artifacts", jobId) + u := fmt.Sprintf("jobs/%s/artifacts", railsPathEscape(jobId)) payload := ArtifactBatchUpdateRequest{} for id, state := range artifactStates { @@ -133,7 +133,7 @@ func (c *Client) UpdateArtifacts(ctx context.Context, jobId string, artifactStat // SearchArtifacts searches Buildkite for a set of artifacts func (c *Client) SearchArtifacts(ctx context.Context, buildId string, opt *ArtifactSearchOptions) ([]*Artifact, *Response, error) { - u := fmt.Sprintf("builds/%s/artifacts/search", buildId) + u := fmt.Sprintf("builds/%s/artifacts/search", railsPathEscape(buildId)) u, err := addOptions(u, opt) if err != nil { return nil, nil, err diff --git a/vendor/github.com/buildkite/agent/v3/api/chunks.go b/vendor/github.com/buildkite/agent/v3/api/chunks.go index 71a1a1b33..d238584b3 100644 --- a/vendor/github.com/buildkite/agent/v3/api/chunks.go +++ b/vendor/github.com/buildkite/agent/v3/api/chunks.go @@ -10,9 +10,9 @@ import ( // Chunk represents a Buildkite Agent API Chunk type Chunk struct { Data []byte - Sequence int - Offset int - Size int + Sequence uint64 + Offset uint64 + Size uint64 } // Uploads the chunk to the Buildkite Agent API. This request sends the @@ -27,7 +27,7 @@ func (c *Client) UploadChunk(ctx context.Context, jobId string, chunk *Chunk) (* } // Pass most params as query - u := fmt.Sprintf("jobs/%s/chunks?sequence=%d&offset=%d&size=%d", jobId, chunk.Sequence, chunk.Offset, chunk.Size) + u := fmt.Sprintf("jobs/%s/chunks?sequence=%d&offset=%d&size=%d", railsPathEscape(jobId), chunk.Sequence, chunk.Offset, chunk.Size) req, err := c.newFormRequest(ctx, "POST", u, body) if err != nil { return nil, err diff --git a/vendor/github.com/buildkite/agent/v3/api/client.go b/vendor/github.com/buildkite/agent/v3/api/client.go index b3c6d89a7..42aa57bec 100644 --- a/vendor/github.com/buildkite/agent/v3/api/client.go +++ b/vendor/github.com/buildkite/agent/v3/api/client.go @@ -364,3 +364,8 @@ func addOptions(s string, opt any) (string, error) { func joinURLPath(endpoint string, path string) string { return strings.TrimRight(endpoint, "/") + "/" + strings.TrimLeft(path, "/") } + +// Rails doesn't accept dots in some path segments. +func railsPathEscape(s string) string { + return strings.ReplaceAll(url.PathEscape(s), ".", "%2E") +} diff --git a/vendor/github.com/buildkite/agent/v3/api/header_times.go b/vendor/github.com/buildkite/agent/v3/api/header_times.go index 5302d7b66..4a5283404 100644 --- a/vendor/github.com/buildkite/agent/v3/api/header_times.go +++ b/vendor/github.com/buildkite/agent/v3/api/header_times.go @@ -13,7 +13,7 @@ type HeaderTimes struct { // SaveHeaderTimes saves the header times to the job func (c *Client) SaveHeaderTimes(ctx context.Context, jobId string, headerTimes *HeaderTimes) (*Response, error) { - u := fmt.Sprintf("jobs/%s/header_times", jobId) + u := fmt.Sprintf("jobs/%s/header_times", railsPathEscape(jobId)) req, err := c.newRequest(ctx, "POST", u, headerTimes) if err != nil { diff --git a/vendor/github.com/buildkite/agent/v3/api/jobs.go b/vendor/github.com/buildkite/agent/v3/api/jobs.go index 4dee5af4c..1b9805519 100644 --- a/vendor/github.com/buildkite/agent/v3/api/jobs.go +++ b/vendor/github.com/buildkite/agent/v3/api/jobs.go @@ -3,23 +3,28 @@ package api import ( "context" "fmt" + + "github.com/buildkite/agent/v3/internal/pipeline" ) // Job represents a Buildkite Agent API Job type Job struct { - ID string `json:"id,omitempty"` - Endpoint string `json:"endpoint"` - State string `json:"state,omitempty"` - Env map[string]string `json:"env,omitempty"` - ChunksMaxSizeBytes int `json:"chunks_max_size_bytes,omitempty"` - Token string `json:"token,omitempty"` - ExitStatus string `json:"exit_status,omitempty"` - Signal string `json:"signal,omitempty"` - SignalReason string `json:"signal_reason,omitempty"` - StartedAt string `json:"started_at,omitempty"` - FinishedAt string `json:"finished_at,omitempty"` - RunnableAt string `json:"runnable_at,omitempty"` - ChunksFailedCount int `json:"chunks_failed_count,omitempty"` + ID string `json:"id,omitempty"` + Endpoint string `json:"endpoint"` + State string `json:"state,omitempty"` + Env map[string]string `json:"env,omitempty"` + Step pipeline.CommandStep `json:"step,omitempty"` + MatrixPermutation pipeline.MatrixPermutation `json:"matrix_permutation,omitempty"` + ChunksMaxSizeBytes uint64 `json:"chunks_max_size_bytes,omitempty"` + LogMaxSizeBytes uint64 `json:"log_max_size_bytes,omitempty"` + Token string `json:"token,omitempty"` + ExitStatus string `json:"exit_status,omitempty"` + Signal string `json:"signal,omitempty"` + SignalReason string `json:"signal_reason,omitempty"` + StartedAt string `json:"started_at,omitempty"` + FinishedAt string `json:"finished_at,omitempty"` + RunnableAt string `json:"runnable_at,omitempty"` + ChunksFailedCount int `json:"chunks_failed_count,omitempty"` } type JobState struct { @@ -40,7 +45,7 @@ type jobFinishRequest struct { // GetJobState returns the state of a given job func (c *Client) GetJobState(ctx context.Context, id string) (*JobState, *Response, error) { - u := fmt.Sprintf("jobs/%s", id) + u := fmt.Sprintf("jobs/%s", railsPathEscape(id)) req, err := c.newRequest(ctx, "GET", u, nil) if err != nil { @@ -58,7 +63,7 @@ func (c *Client) GetJobState(ctx context.Context, id string) (*JobState, *Respon // Acquires a job using its ID func (c *Client) AcquireJob(ctx context.Context, id string, headers ...Header) (*Job, *Response, error) { - u := fmt.Sprintf("jobs/%s/acquire", id) + u := fmt.Sprintf("jobs/%s/acquire", railsPathEscape(id)) req, err := c.newRequest(ctx, "PUT", u, nil, headers...) if err != nil { @@ -78,7 +83,7 @@ func (c *Client) AcquireJob(ctx context.Context, id string, headers ...Header) ( // environment variables (when a job is accepted, the agents environment is // applied to the job) func (c *Client) AcceptJob(ctx context.Context, job *Job) (*Job, *Response, error) { - u := fmt.Sprintf("jobs/%s/accept", job.ID) + u := fmt.Sprintf("jobs/%s/accept", railsPathEscape(job.ID)) req, err := c.newRequest(ctx, "PUT", u, nil) if err != nil { @@ -96,7 +101,7 @@ func (c *Client) AcceptJob(ctx context.Context, job *Job) (*Job, *Response, erro // StartJob starts the passed in job func (c *Client) StartJob(ctx context.Context, job *Job) (*Response, error) { - u := fmt.Sprintf("jobs/%s/start", job.ID) + u := fmt.Sprintf("jobs/%s/start", railsPathEscape(job.ID)) req, err := c.newRequest(ctx, "PUT", u, &jobStartRequest{ StartedAt: job.StartedAt, @@ -110,7 +115,7 @@ func (c *Client) StartJob(ctx context.Context, job *Job) (*Response, error) { // FinishJob finishes the passed in job func (c *Client) FinishJob(ctx context.Context, job *Job) (*Response, error) { - u := fmt.Sprintf("jobs/%s/finish", job.ID) + u := fmt.Sprintf("jobs/%s/finish", railsPathEscape(job.ID)) req, err := c.newRequest(ctx, "PUT", u, &jobFinishRequest{ FinishedAt: job.FinishedAt, diff --git a/vendor/github.com/buildkite/agent/v3/api/meta_data.go b/vendor/github.com/buildkite/agent/v3/api/meta_data.go index 384c2e748..a9a591320 100644 --- a/vendor/github.com/buildkite/agent/v3/api/meta_data.go +++ b/vendor/github.com/buildkite/agent/v3/api/meta_data.go @@ -20,7 +20,7 @@ type MetaDataExists struct { // Sets the meta data value func (c *Client) SetMetaData(ctx context.Context, jobId string, metaData *MetaData) (*Response, error) { - u := fmt.Sprintf("jobs/%s/data/set", jobId) + u := fmt.Sprintf("jobs/%s/data/set", railsPathEscape(jobId)) req, err := c.newRequest(ctx, "POST", u, metaData) if err != nil { @@ -36,7 +36,7 @@ func (c *Client) GetMetaData(ctx context.Context, scope, id, key string) (*MetaD return nil, nil, errors.New("scope must either be job or build") } - u := fmt.Sprintf("%ss/%s/data/get", scope, id) + u := fmt.Sprintf("%ss/%s/data/get", scope, railsPathEscape(id)) m := &MetaData{Key: key} req, err := c.newRequest(ctx, "POST", u, m) @@ -58,7 +58,7 @@ func (c *Client) ExistsMetaData(ctx context.Context, scope, id, key string) (*Me return nil, nil, errors.New("scope must either be job or build") } - u := fmt.Sprintf("%ss/%s/data/exists", scope, id) + u := fmt.Sprintf("%ss/%s/data/exists", scope, railsPathEscape(id)) m := &MetaData{Key: key} req, err := c.newRequest(ctx, "POST", u, m) @@ -80,7 +80,7 @@ func (c *Client) MetaDataKeys(ctx context.Context, scope, id string) ([]string, return nil, nil, errors.New("scope must either be job or build") } - u := fmt.Sprintf("%ss/%s/data/keys", scope, id) + u := fmt.Sprintf("%ss/%s/data/keys", scope, railsPathEscape(id)) req, err := c.newRequest(ctx, "POST", u, nil) if err != nil { diff --git a/vendor/github.com/buildkite/agent/v3/api/oidc.go b/vendor/github.com/buildkite/agent/v3/api/oidc.go index a25f0302b..d11e35726 100644 --- a/vendor/github.com/buildkite/agent/v3/api/oidc.go +++ b/vendor/github.com/buildkite/agent/v3/api/oidc.go @@ -27,7 +27,7 @@ func (c *Client) OIDCToken(ctx context.Context, methodReq *OIDCTokenRequest) (*O Claims: methodReq.Claims, } - u := fmt.Sprintf("jobs/%s/oidc/tokens", methodReq.Job) + u := fmt.Sprintf("jobs/%s/oidc/tokens", railsPathEscape(methodReq.Job)) httpReq, err := c.newRequest(ctx, "POST", u, m) if err != nil { return nil, nil, err diff --git a/vendor/github.com/buildkite/agent/v3/api/pipelines.go b/vendor/github.com/buildkite/agent/v3/api/pipelines.go index e585fb1cd..323c8479f 100644 --- a/vendor/github.com/buildkite/agent/v3/api/pipelines.go +++ b/vendor/github.com/buildkite/agent/v3/api/pipelines.go @@ -28,7 +28,7 @@ func (c *Client) UploadPipeline( pipeline *PipelineChange, headers ...Header, ) (*Response, error) { - u := fmt.Sprintf("jobs/%s/pipelines?async=true", jobId) + u := fmt.Sprintf("jobs/%s/pipelines?async=true", railsPathEscape(jobId)) req, err := c.newRequest(ctx, "POST", u, pipeline, headers...) if err != nil { @@ -44,7 +44,7 @@ func (c *Client) PipelineUploadStatus( uuid string, headers ...Header, ) (*PipelineUploadStatus, *Response, error) { - u := fmt.Sprintf("jobs/%s/pipelines/%s", jobId, uuid) + u := fmt.Sprintf("jobs/%s/pipelines/%s", railsPathEscape(jobId), railsPathEscape(uuid)) req, err := c.newRequest(ctx, "GET", u, nil, headers...) if err != nil { diff --git a/vendor/github.com/buildkite/agent/v3/api/steps.go b/vendor/github.com/buildkite/agent/v3/api/steps.go index a428b2e1a..b8ab745e7 100644 --- a/vendor/github.com/buildkite/agent/v3/api/steps.go +++ b/vendor/github.com/buildkite/agent/v3/api/steps.go @@ -18,7 +18,7 @@ type StepExportResponse struct { // StepExport gets an attribute from step func (c *Client) StepExport(ctx context.Context, stepIdOrKey string, stepGetRequest *StepExportRequest) (*StepExportResponse, *Response, error) { - u := fmt.Sprintf("steps/%s/export", stepIdOrKey) + u := fmt.Sprintf("steps/%s/export", railsPathEscape(stepIdOrKey)) req, err := c.newRequest(ctx, "POST", u, stepGetRequest) if err != nil { @@ -45,7 +45,7 @@ type StepUpdate struct { // StepUpdate updates a step func (c *Client) StepUpdate(ctx context.Context, stepIdOrKey string, stepUpdate *StepUpdate) (*Response, error) { - u := fmt.Sprintf("steps/%s", stepIdOrKey) + u := fmt.Sprintf("steps/%s", railsPathEscape(stepIdOrKey)) req, err := c.newRequest(ctx, "PUT", u, stepUpdate) if err != nil { diff --git a/vendor/github.com/buildkite/agent/v3/env/environment.go b/vendor/github.com/buildkite/agent/v3/env/environment.go new file mode 100644 index 000000000..a62c5dc7e --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/env/environment.go @@ -0,0 +1,298 @@ +// Package env provides utilities for dealing with environment variables. +// +// It is intended for internal use by buildkite-agent only. +package env + +import ( + "encoding/json" + "runtime" + "sort" + "strings" + + "github.com/puzpuzpuz/xsync/v2" +) + +// Environment is a map of environment variables, with the keys normalized +// for case-insensitive operating systems +type Environment struct { + underlying *xsync.MapOf[string, string] +} + +func New() *Environment { + return &Environment{underlying: xsync.NewMapOf[string]()} +} + +func NewWithLength(length int) *Environment { + return &Environment{underlying: xsync.NewMapOfPresized[string](length)} +} + +func FromMap(m map[string]string) *Environment { + env := &Environment{underlying: xsync.NewMapOfPresized[string](len(m))} + + for k, v := range m { + env.Set(k, v) + } + + return env +} + +// Split splits an environment variable (in the form "name=value") into the name +// and value substrings. If there is no '=', or the first '=' is at the start, +// it returns `"", "", false`. +func Split(l string) (name, value string, ok bool) { + // Variable names should not contain '=' on any platform...and yet Windows + // creates environment variables beginning with '=' in some circumstances. + // See https://github.com/golang/go/issues/49886. + // Dropping them matches the previous behaviour on Windows, which used SET + // to obtain the state of environment variables. + i := strings.IndexRune(l, '=') + // Either there is no '=', or it is at the start of the string. + // Both are disallowed. + if i <= 0 { + return "", "", false + } + return l[:i], l[i+1:], true +} + +// FromSlice creates a new environment from a string slice of KEY=VALUE +func FromSlice(s []string) *Environment { + env := NewWithLength(len(s)) + + for _, l := range s { + if k, v, ok := Split(l); ok { + env.Set(k, v) + } + } + + return env +} + +// Dump returns a copy of the environment with all keys normalized +func (e *Environment) Dump() map[string]string { + d := make(map[string]string, e.underlying.Size()) + e.underlying.Range(func(k, v string) bool { + d[normalizeKeyName(k)] = v + return true + }) + + return d +} + +// Get returns a key from the environment +func (e *Environment) Get(key string) (string, bool) { + v, ok := e.underlying.Load(normalizeKeyName(key)) + return v, ok +} + +// Get a boolean value from environment, with a default for empty. Supports true|false, on|off, 1|0 +func (e *Environment) GetBool(key string, defaultValue bool) bool { + v, _ := e.Get(key) + + switch strings.ToLower(v) { + case "on", "1", "enabled", "true": + return true + case "off", "0", "disabled", "false": + return false + default: + return defaultValue + } +} + +// Exists returns true/false depending on whether or not the key exists in the env +func (e *Environment) Exists(key string) bool { + _, ok := e.underlying.Load(normalizeKeyName(key)) + return ok +} + +// Set sets a key in the environment +func (e *Environment) Set(key string, value string) string { + e.underlying.Store(normalizeKeyName(key), value) + return value +} + +// Remove a key from the Environment and return its value +func (e *Environment) Remove(key string) string { + value, ok := e.Get(key) + if ok { + e.underlying.Delete(normalizeKeyName(key)) + } + return value +} + +// Length returns the length of the environment +func (e *Environment) Length() int { + return e.underlying.Size() +} + +// Diff returns a new environment with the keys and values from this +// environment which are different in the other one. +func (e *Environment) Diff(other *Environment) Diff { + diff := Diff{ + Added: make(map[string]string), + Changed: make(map[string]DiffPair), + Removed: make(map[string]struct{}, 0), + } + + if other == nil { + e.underlying.Range(func(k, _ string) bool { + diff.Removed[k] = struct{}{} + return true + }) + + return diff + } + + e.underlying.Range(func(k, v string) bool { + other, ok := other.Get(k) + if !ok { + // This environment has added this key to other + diff.Added[k] = v + return true + } + + if other != v { + diff.Changed[k] = DiffPair{ + Old: other, + New: v, + } + } + + return true + }) + + other.underlying.Range(func(k, _ string) bool { + if _, ok := e.Get(k); !ok { + diff.Removed[k] = struct{}{} + } + + return true + }) + + return diff +} + +// Merge merges another env into this one and returns the result +func (e *Environment) Merge(other *Environment) { + if other == nil { + return + } + + other.underlying.Range(func(k, v string) bool { + e.Set(k, v) + return true + }) +} + +func (e *Environment) Apply(diff Diff) { + for k, v := range diff.Added { + e.Set(k, v) + } + for k, v := range diff.Changed { + e.Set(k, v.New) + } + for k := range diff.Removed { + e.Remove(k) + } +} + +// Copy returns a copy of the env +func (e *Environment) Copy() *Environment { + if e == nil { + return New() + } + + c := New() + + e.underlying.Range(func(k, v string) bool { + c.Set(k, v) + return true + }) + + return c +} + +// ToSlice returns a sorted slice representation of the environment +func (e *Environment) ToSlice() []string { + s := []string{} + e.underlying.Range(func(k, v string) bool { + s = append(s, k+"="+v) + return true + }) + + // Ensure they are in a consistent order (helpful for tests) + sort.Strings(s) + + return s +} + +func (e *Environment) MarshalJSON() ([]byte, error) { + return json.Marshal(e.Dump()) +} + +func (e *Environment) UnmarshalJSON(data []byte) error { + var raw map[string]string + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + + e.underlying = xsync.NewMapOfPresized[string](len(raw)) + for k, v := range raw { + e.Set(k, v) + } + + return nil +} + +// Environment variables on Windows are case-insensitive. When you run `SET` +// within a Windows command prompt, you'll see variables like this: +// +// ... +// Path=C:\Program Files (x86)\Parallels\Parallels Tools\Applications;... +// PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 94 Stepping 3, GenuineIntel +// SystemDrive=C: +// SystemRoot=C:\Windows +// ... +// +// There's a mix of both CamelCase and UPPERCASE, but the can all be accessed +// regardless of the case you use. So PATH is the same as Path, PAth, pATH, +// and so on. +// +// os.Environ() in Golang returns key/values in the original casing, so it +// returns a slice like this: +// +// { "Path=...", "PROCESSOR_IDENTIFIER=...", "SystemRoot=..." } +// +// Users of env.Environment shouldn't need to care about this. +// env.Get("PATH") should "just work" on Windows. This means on Windows +// machines, we'll normalise all the keys that go in/out of this API. +// +// Unix systems _are_ case sensitive when it comes to ENV, so we'll just leave +// that alone. +func normalizeKeyName(key string) string { + if runtime.GOOS == "windows" { + return strings.ToUpper(key) + } else { + return key + } +} + +type Diff struct { + Added map[string]string + Changed map[string]DiffPair + Removed map[string]struct{} +} + +type DiffPair struct { + Old string + New string +} + +func (diff *Diff) Remove(key string) { + delete(diff.Added, key) + delete(diff.Changed, key) + delete(diff.Removed, key) +} + +func (diff *Diff) Empty() bool { + return len(diff.Added) == 0 && len(diff.Changed) == 0 && len(diff.Removed) == 0 +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/ordered/map.go b/vendor/github.com/buildkite/agent/v3/internal/ordered/map.go new file mode 100644 index 000000000..eb521d746 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/ordered/map.go @@ -0,0 +1,417 @@ +// Package ordered implements an ordered map type. +package ordered + +import ( + "bytes" + "encoding/json" + "fmt" + + "github.com/google/go-cmp/cmp" + "gopkg.in/yaml.v3" +) + +var _ interface { + json.Marshaler + json.Unmarshaler + yaml.IsZeroer + yaml.Marshaler + yaml.Unmarshaler +} = (*Map[string, any])(nil) + +// Map is an order-preserving map with string keys. It is intended for working +// with YAML in an order-preserving way (off-spec, strictly speaking) and JSON +// (more of the same). +type Map[K comparable, V any] struct { + items []Tuple[K, V] + index map[K]int +} + +// MapSS is a convenience alias to reduce keyboard wear. +type MapSS = Map[string, string] + +// MapSA is a convenience alias to reduce keyboard wear. +type MapSA = Map[string, any] + +// NewMap returns a new empty map with a given initial capacity. +func NewMap[K comparable, V any](cap int) *Map[K, V] { + return &Map[K, V]{ + items: make([]Tuple[K, V], 0, cap), + index: make(map[K]int, cap), + } +} + +// MapFromItems creates an Map with some items. +func MapFromItems[K comparable, V any](ps ...Tuple[K, V]) *Map[K, V] { + m := NewMap[K, V](len(ps)) + for _, p := range ps { + m.Set(p.Key, p.Value) + } + return m +} + +// Len returns the number of items in the map. +func (m *Map[K, V]) Len() int { + if m == nil { + return 0 + } + return len(m.index) +} + +// IsZero reports if m is nil or empty. It is used by yaml.v3 to check +// emptiness. +func (m *Map[K, V]) IsZero() bool { + return m == nil || len(m.index) == 0 +} + +// Get retrieves the value associated with a key, and reports if it was found. +func (m *Map[K, V]) Get(k K) (V, bool) { + var zv V + if m == nil { + return zv, false + } + idx, ok := m.index[k] + if !ok { + return zv, false + } + return m.items[idx].Value, true +} + +// Contains reports if the map contains the key. +func (m *Map[K, V]) Contains(k K) bool { + if m == nil { + return false + } + _, has := m.index[k] + return has +} + +// Set sets the value for the given key. If the key exists, it remains in its +// existing spot, otherwise it is added to the end of the map. +func (m *Map[K, V]) Set(k K, v V) { + // Suppose someone makes Map with new(Map). The one thing we need to not be + // nil will be nil. + if m.index == nil { + m.index = make(map[K]int, 1) + } + + // Replace existing value? + if idx, exists := m.index[k]; exists { + m.items[idx].Value = v + return + } + + // Append new item. + m.index[k] = len(m.items) + m.items = append(m.items, Tuple[K, V]{ + Key: k, + Value: v, + }) +} + +// Replace replaces an old key in the same spot with a new key and value. +// If the old key doesn't exist in the map, the item is inserted at the end. +// If the new key already exists in the map (and isn't equal to the old key), +// then it is deleted. +// This provides a way to change a single key in-place (easier than deleting the +// old key and all later keys, adding the new key, then restoring the rest). +func (m *Map[K, V]) Replace(old, new K, v V) { + // Suppose someone makes Map with new(Map). The one thing we need to not be + // nil will be nil. + if m.index == nil { + m.index = make(map[K]int, 1) + } + + // idx is where the item will go + idx, exists := m.index[old] + if !exists { + // Point idx at the end of m.items and ensure there is an item there. + idx = len(m.items) + m.items = append(m.items, Tuple[K, V]{}) + } + + // If the key changed, there's some tidyup... + if old != new { + // If "new" already exists in the map, then delete it first. The intent + // of Replace is to put the item where "old" is but under "new", so if + // "new" already exists somewhere else, adding it where "old" is would + // be getting out of hand (now there are two of them). + if newidx, exists := m.index[new]; exists { + m.items[newidx].deleted = true + } + + // Delete "old" from the index and update "new" to point to idx + delete(m.index, old) + m.index[new] = idx + } + + // Put the item into m.items at idx. + m.items[idx] = Tuple[K, V]{ + Key: new, + Value: v, + } +} + +// Delete deletes a key from the map. It does nothing if the key is not in the +// map. +func (m *Map[K, V]) Delete(k K) { + if m == nil { + return + } + idx, ok := m.index[k] + if !ok { + return + } + m.items[idx].deleted = true + delete(m.index, k) + + // If half the pairs have been deleted, perform a compaction. + if len(m.items) >= 2*len(m.index) { + m.compact() + } +} + +// ToMap creates a regular (un-ordered) map containing the same data. If m is +// nil, ToMap returns nil. +func (m *Map[K, V]) ToMap() map[K]V { + if m == nil { + return nil + } + um := make(map[K]V, len(m.index)) + m.Range(func(k K, v V) error { + um[k] = v + return nil + }) + return um +} + +// ToMapRecursive converts a weakly typed nested structure consisting of +// *Map[string, any], []any, and any (i.e. output from DecodeYAML), +// into one containing the same data but where each *Map[string, any] is +// map[string]any. +func ToMapRecursive(src any) any { + switch tsrc := src.(type) { + case *Map[string, any]: + um := make(map[string]any, len(tsrc.index)) + tsrc.Range(func(k string, v any) error { + um[k] = ToMapRecursive(v) + return nil + }) + return um + + case []any: + s := make([]any, len(tsrc)) + for i, e := range tsrc { + s[i] = ToMapRecursive(e) + } + return s + + default: + return src + } +} + +// Equal reports if the two maps are equal (they contain the same items in the +// same order). Keys are compared directly; values are compared using go-cmp +// (provided with Equal[string, any] and Equal[string, string] as a comparers). +func Equal[K comparable, V any](a, b *Map[K, V]) bool { + if a == nil || b == nil { + return a == b + } + if a.Len() != b.Len() { + return false + } + i, j := 0, 0 + for i < len(a.items) && j < len(b.items) { + for a.items[i].deleted { + i++ + } + for b.items[j].deleted { + j++ + } + if a.items[i].Key != b.items[j].Key { + return false + } + if !cmp.Equal(a.items[i].Value, b.items[j].Value, cmp.Comparer(Equal[string, string]), cmp.Comparer(Equal[string, any])) { + return false + } + i++ + j++ + } + return true +} + +// EqualSS is a convenience alias to reduce keyboard wear. +var EqualSS = Equal[string, string] + +// EqualSA is a convenience alias to reduce keyboard wear. +var EqualSA = Equal[string, any] + +// compact re-organises the internal storage of the Map. +func (m *Map[K, V]) compact() { + pairs := make([]Tuple[K, V], 0, len(m.index)) + for _, p := range m.items { + if p.deleted { + continue + } + m.index[p.Key] = len(pairs) + pairs = append(pairs, Tuple[K, V]{ + Key: p.Key, + Value: p.Value, + }) + } + m.items = pairs +} + +// Range ranges over the map (in order). If f returns an error, it stops ranging +// and returns that error. +func (m *Map[K, V]) Range(f func(k K, v V) error) error { + if m.IsZero() { + return nil + } + for _, p := range m.items { + if p.deleted { + continue + } + if err := f(p.Key, p.Value); err != nil { + return err + } + } + return nil +} + +// MarshalJSON marshals the ordered map to JSON. It preserves the map order in +// the output. +func (m *Map[K, V]) MarshalJSON() ([]byte, error) { + // NB: writes to b don't error, but JSON encoding could error. + var b bytes.Buffer + enc := json.NewEncoder(&b) + b.WriteRune('{') + first := true + err := m.Range(func(k K, v V) error { + if !first { + // Separating comma. + b.WriteRune(',') + } + first = false + if err := enc.Encode(k); err != nil { + return err + } + b.WriteRune(':') + return enc.Encode(v) + }) + if err != nil { + return nil, err + } + b.WriteRune('}') + return b.Bytes(), nil +} + +// MarshalYAML returns a *yaml.Node encoding this map (in order), or an error +// if any of the items could not be encoded into a *yaml.Node. +func (m *Map[K, V]) MarshalYAML() (any, error) { + n := &yaml.Node{ + Kind: yaml.MappingNode, + Tag: "!!map", + } + err := m.Range(func(k K, v V) error { + nk, nv := new(yaml.Node), new(yaml.Node) + if err := nk.Encode(k); err != nil { + return err + } + if err := nv.Encode(v); err != nil { + return err + } + n.Content = append(n.Content, nk, nv) + return nil + }) + + if err != nil { + return nil, err + } + return n, nil +} + +// UnmarshalJSON unmarshals to JSON. It only supports K = string. +// This is yaml.Unmarshal in a trenchcoat (YAML is a superset of JSON). +func (m *Map[K, V]) UnmarshalJSON(b []byte) error { + return yaml.Unmarshal(b, m) +} + +// UnmarshalYAML unmarshals a YAML mapping node into this map. It only supports +// K = string. Where yaml.v3 typically infers map[string]any for unmarshaling +// mappings into any, this method chooses *Map[string, any] instead. +// If V = *yaml.Node, then the value nodes are not decoded. This is useful for +// a shallow unmarshaling step. +func (m *Map[K, V]) UnmarshalYAML(n *yaml.Node) error { + om, ok := any(m).(*Map[string, V]) + if !ok { + var zk K + return fmt.Errorf("cannot unmarshal into ordered.Map with key type %T (want string)", zk) + } + + if n.Kind != yaml.MappingNode { + return fmt.Errorf("line %d, col %d: wrong kind (got %x, want %x)", n.Line, n.Column, n.Kind, yaml.MappingNode) + } + + switch tm := any(m).(type) { + case *Map[string, any]: + // Use DecodeYAML, then steal the contents. + sm, err := DecodeYAML(n) + if err != nil { + return err + } + *tm = *sm.(*Map[string, any]) + return nil + + case *Map[string, *yaml.Node]: + // Load into the map without any value decoding. + return rangeYAMLMap(n, func(key string, val *yaml.Node) error { + tm.Set(key, val) + return nil + }) + + default: + return rangeYAMLMap(n, func(key string, val *yaml.Node) error { + // Try DecodeYAML? (maybe V is a type like []any). + nv, err := DecodeYAML(val) + if err != nil { + return err + } + v, ok := nv.(V) + if !ok { + // Let yaml.v3 choose what to do with the specific type. + if err := val.Decode(&v); err != nil { + return err + } + } + om.Set(key, v) + return nil + }) + } +} + +// AssertValues converts a map with "any" values into a map with V values by +// type-asserting each value. It returns an error if any value is not +// assertable to V. +func AssertValues[V any](m *MapSA) (*Map[string, V], error) { + msv := NewMap[string, V](m.Len()) + return msv, m.Range(func(k string, v any) error { + t, ok := v.(V) + if !ok { + return fmt.Errorf("value for key %q (type %T) is not assertable to %T", k, v, t) + } + msv.Set(k, t) + return nil + }) +} + +// TransformValues converts a map with V1 values into a map with V2 values by +// running each value through a function. +func TransformValues[K comparable, V1, V2 any](m *Map[K, V1], f func(V1) V2) *Map[K, V2] { + m2 := NewMap[K, V2](m.Len()) + m.Range(func(k K, v V1) error { + m2.Set(k, f(v)) + return nil + }) + return m2 +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/ordered/slice.go b/vendor/github.com/buildkite/agent/v3/internal/ordered/slice.go new file mode 100644 index 000000000..b60ad39c3 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/ordered/slice.go @@ -0,0 +1,30 @@ +package ordered + +import ( + "fmt" + + "gopkg.in/yaml.v3" +) + +var _ yaml.Unmarshaler = (*Slice)(nil) + +// Slice is []any, but unmarshaling into it prefers *Map[string,any] over +// map[string]any. +type Slice []any + +// UnmarshalYAML unmarshals sequence nodes. Any mapping nodes are unmarshaled +// as *Map[string,any]. +func (s *Slice) UnmarshalYAML(n *yaml.Node) error { + if n.Kind != yaml.SequenceNode { + return fmt.Errorf("line %d, col %d: unsupported kind %x for unmarshaling Slice (want %x)", n.Line, n.Column, n.Kind, yaml.SequenceNode) + } + seen := make(map[*yaml.Node]bool) + for _, c := range n.Content { + cv, err := decodeYAML(seen, c) + if err != nil { + return err + } + *s = append(*s, cv) + } + return nil +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/ordered/strings.go b/vendor/github.com/buildkite/agent/v3/internal/ordered/strings.go new file mode 100644 index 000000000..198af399d --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/ordered/strings.go @@ -0,0 +1,39 @@ +package ordered + +import ( + "fmt" + + "gopkg.in/yaml.v3" +) + +// Strings is []string, but unmarshaling handles both sequences and single +// scalars. +type Strings []string + +// UnmarshalYAML unmarshals n depending on its Kind as either +// - a sequence of strings (into a slice), or +// - a single string (into a one-element slice). +// For example, unmarshaling either `["foo"]` or `"foo"` should result in a +// one-element slice (`Strings{"foo"}`). +func (s *Strings) UnmarshalYAML(n *yaml.Node) error { + switch n.Kind { + case yaml.ScalarNode: + var x string + if err := n.Decode(&x); err != nil { + return err + } + *s = append(*s, x) + + case yaml.SequenceNode: + var xs []string + if err := n.Decode(&xs); err != nil { + return err + } + *s = append(*s, xs...) + + default: + return fmt.Errorf("line %d, col %d: unsupported kind %x for unmarshaling Strings (want %x or %x)", n.Line, n.Column, n.Kind, yaml.ScalarNode, yaml.SequenceNode) + } + + return nil +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/ordered/tuple.go b/vendor/github.com/buildkite/agent/v3/internal/ordered/tuple.go new file mode 100644 index 000000000..4c9006f8e --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/ordered/tuple.go @@ -0,0 +1,15 @@ +package ordered + +// Tuple is used for storing values in Map. +type Tuple[K comparable, V any] struct { + Key K + Value V + + deleted bool +} + +// TupleSS is a convenience alias to reduce keyboard wear. +type TupleSS = Tuple[string, string] + +// TupleSA is a convenience alias to reduce keyboard wear. +type TupleSA = Tuple[string, any] diff --git a/vendor/github.com/buildkite/agent/v3/internal/ordered/unmarshal.go b/vendor/github.com/buildkite/agent/v3/internal/ordered/unmarshal.go new file mode 100644 index 000000000..fb254093e --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/ordered/unmarshal.go @@ -0,0 +1,384 @@ +package ordered + +import ( + "errors" + "fmt" + "reflect" + "strings" + + "gopkg.in/yaml.v3" +) + +// Errors that can be returned by Unmarshal +// (typically wrapped - use errors.Is). +var ( + ErrIntoNonPointer = errors.New("cannot unmarshal into non-pointer") + ErrIntoNil = errors.New("cannot unmarshal into nil") + ErrIncompatibleTypes = errors.New("incompatible types") + ErrUnsupportedSrc = errors.New("cannot unmarshal from src") + ErrMultipleInlineFields = errors.New(`multiple fields tagged with yaml:",inline"`) +) + +// Unmarshaler is an interface that types can use to override the default +// unmarshaling behaviour. +type Unmarshaler interface { + // UnmarshalOrdered should unmarshal src into the implementing value. src + // will generally be one of *Map[string, any], []any, or a "scalar" built-in + // type. + UnmarshalOrdered(src any) error +} + +// Unmarshal recursively unmarshals src into dst. src and dst can be a variety +// of types under the hood, but some combinations don't work. Good luck! +// +// - If dst is nil, then src must be nil. +// - If src is yaml.Node or *yaml.Node, then DecodeYAML is called to translate +// the node into another type. +// - If dst is a pointer and src is nil, then the value dst points to is set +// to zero. +// - If dst is a pointer to a pointer, Unmarshal recursively calls Unmarshal +// on the inner pointer, creating a new value of the type being pointed to +// as needed. +// - If dst implements Unmarshaler, Unmarshal returns +// dst.UnmarshalOrdered(src). +// - If dst is *any, Unmarshal copies src directly into *dst. +// +// Otherwise, it acts a lot like yaml.Unmarshal, except that the type S of src +// and type D of dst can be one of the following: +// +// - S = *Map[string, any] (recursively containing values with types from this +// list); D must be one of: a pointer to a struct with yaml tags, +// or a map or a pointer to a map (either *Map or map) with string keys. +// yaml tags includes ",inline". Inline fields must themselves be a type +// that Unmarshal can unmarshal *Map[string, any] into - another struct or +// Map or map with string keys. +// - S = []any (also recursively containing values with types from this list), +// which is recursively unmarshaled elementwise; D is *[]any or +// *[]somethingElse. +// - S ∊ {string, float64, int, bool}; D must be *S (value copied directly), +// *[]S or *[]any (value appended), *string (value formatted through +// fmt.Sprint) or *[]string (formatted value appended). +func Unmarshal(src, dst any) error { + if dst == nil { + // This is interface nil (not typed nil, which has to be tested after + // figuring out the types). + if src == nil { + // Unmarshal nil into nil? Seems legit + return nil + } + return ErrIntoNil + } + + // Apply DecodeYAML to yaml.Node or *yaml.Node first. + switch n := src.(type) { + case yaml.Node: + o, err := DecodeYAML(&n) + if err != nil { + return err + } + src = o + + case *yaml.Node: + o, err := DecodeYAML(n) + if err != nil { + return err + } + src = o + } + + if um, ok := dst.(Unmarshaler); ok { + return um.UnmarshalOrdered(src) + } + + // Handle typed nil pointers, pointers to nil, and pointers to pointers. + // Note that vdst could still be a map. + vdst := reflect.ValueOf(dst) + + // First, handle src == nil. dst must be a pointer to something or nil. + if src == nil { + if vdst.Kind() != reflect.Pointer { + return fmt.Errorf("%w (%T)", ErrIntoNonPointer, dst) + } + if vdst.IsNil() { + // Unmarshaling nil into nil... seems legit. + return nil + } + // Zero out the value pointed to by dst. + vdst.Elem().SetZero() + return nil + } + + // src is not nil. dst is usually a pointer - is it nil? pointer to pointer? + if vdst.Kind() == reflect.Pointer { + // Unmarshaling into typed nil value? + if vdst.IsNil() { + return ErrIntoNil + } + + // Non-nil pointer to something. Another pointer? + if edst := vdst.Elem(); edst.Kind() == reflect.Pointer { + // The type of the value being double-pointed to. + innerType := edst.Type().Elem() + if edst.IsNil() { + // Create a new value of the inner type. + edst.Set(reflect.New(innerType)) + } + + // Handle double pointers by recursing on the inner layer. + return Unmarshal(src, edst.Interface()) + } + } + + if tdst, ok := dst.(*any); ok { + *tdst = src + return nil + } + + switch tsrc := src.(type) { + case *Map[string, any]: + return tsrc.decodeInto(dst) + + case []any: + switch tdst := dst.(type) { + case *[]any: + *tdst = append(*tdst, tsrc...) + + default: + if vdst.Kind() != reflect.Pointer { + return fmt.Errorf("%w (%T)", ErrIntoNonPointer, dst) + } + sdst := vdst.Elem() // The slice we append to, reflectively + if sdst.Kind() != reflect.Slice { + return fmt.Errorf("%w: cannot unmarshal []any into %T", ErrIncompatibleTypes, dst) + } + etype := sdst.Type().Elem() // E = Type of the slice's elements + for _, a := range tsrc { + x := reflect.New(etype) // *E + if err := Unmarshal(a, x.Interface()); err != nil { + return err + } + sdst = reflect.Append(sdst, x.Elem()) + } + vdst.Elem().Set(sdst) + } + + case string: + return unmarshalScalar(tsrc, dst) + + case float64: + return unmarshalScalar(tsrc, dst) + + case int: + return unmarshalScalar(tsrc, dst) + + case bool: + return unmarshalScalar(tsrc, dst) + + default: + return fmt.Errorf("%w %T", ErrUnsupportedSrc, src) + } + + return nil +} + +func unmarshalScalar[S any](src S, dst any) error { + switch tdst := dst.(type) { + case *S: + *tdst = src + + case *[]S: + *tdst = append(*tdst, src) + + case *[]any: + *tdst = append(*tdst, src) + + case *string: + *tdst = fmt.Sprint(src) + + case *[]string: + *tdst = append(*tdst, fmt.Sprint(src)) + + default: + return fmt.Errorf("%w: cannot unmarshal %T into %T", ErrIncompatibleTypes, src, dst) + } + return nil +} + +// decodeInto loads the contents of the map into the target (pointer to struct). +// It behaves sort of like `yaml.Node.Decode`: +// +// - If target is a map type with string keys, it unmarshals its contents +// elementwise, with values passed through Unmarshal. +// - If target is *struct{...}, it matches keys to exported fields either +// by looking at `yaml` tags, or using lowercased field names. +// - If a field has a yaml:",inline" tag, it copies any leftover values into +// that field, which must have type map[string]any or any. (Structs are not +// supported for inline.) +func (m *Map[K, V]) decodeInto(target any) error { + tm, ok := any(m).(*Map[string, any]) + if !ok { + return fmt.Errorf("%w: cannot unmarshal from %T, want K=string, V=any", ErrIncompatibleTypes, m) + } + + // Work out the kind of target being used. + // Dereference the target to find the inner value, if needed. + targetValue := reflect.ValueOf(target) + var innerValue reflect.Value + switch targetValue.Kind() { + case reflect.Pointer: + // Passed a pointer to something. + if targetValue.IsNil() { + return ErrIntoNil + } + innerValue = targetValue.Elem() + + case reflect.Map: + // Passed a map directly. + innerValue = targetValue + if innerValue.IsNil() { + return ErrIntoNil + } + + default: + return fmt.Errorf("%w: cannot unmarshal %T into %T, want map or *struct{...}", ErrIncompatibleTypes, m, target) + } + + switch innerValue.Kind() { + case reflect.Map: + // Process the map directly. + mapType := innerValue.Type() + // For simplicity, require the key type to be string. + if keyType := mapType.Key(); keyType.Kind() != reflect.String { + return fmt.Errorf("%w for map key: cannot unmarshal %T into %T", ErrIncompatibleTypes, m, target) + } + + // If target is a pointer to a nil map (with type), create a new map. + if innerValue.IsNil() { + innerValue.Set(reflect.MakeMapWithSize(mapType, tm.Len())) + } + + valueType := mapType.Elem() + return tm.Range(func(k string, v any) error { + nv := reflect.New(valueType) + if err := Unmarshal(v, nv.Interface()); err != nil { + return err + } + innerValue.SetMapIndex(reflect.ValueOf(k), nv.Elem()) + return nil + }) + + case reflect.Struct: + // The rest of the method is concerned with this. + default: + return fmt.Errorf("%w: cannot unmarshal %T into %T", ErrIncompatibleTypes, m, target) + } + + // These are the (accessible by reflection) fields it has. + // This includes non-exported fields. + fields := reflect.VisibleFields(innerValue.Type()) + + var inlineField reflect.StructField + outlineKeys := make(map[string]struct{}) + + for _, field := range fields { + // Skip non-exported fields. This is conventional *and* correct. + if !field.IsExported() { + continue + } + + // No worries if the tag is not there - apply defaults. + tag, _ := field.Tag.Lookup("yaml") + + switch tag { + case "-": + // Note: if a field is skipped with "-", yaml.v3 still puts it into + // inline. + continue + + case ",inline": + if inlineField.Index != nil { + return fmt.Errorf("%w %T", ErrMultipleInlineFields, target) + } + inlineField = field + continue + } + + // default: + key, _, _ := strings.Cut(tag, ",") + if key == "" { + // yaml.v3 convention: + // "Struct fields ... are unmarshalled using the field name + // lowercased as the default key." + key = strings.ToLower(field.Name) + } + + // Is there a value for this key? + v, has := tm.Get(key) + if !has { + continue + } + + // Now load v into this field. + outlineKeys[key] = struct{}{} + + // Get a pointer to the field. This works because target is a pointer. + ptrToField := innerValue.FieldByIndex(field.Index).Addr() + if err := Unmarshal(v, ptrToField.Interface()); err != nil { + return err + } + } + + if inlineField.Index == nil { + return nil + } + // The rest is handling the ",inline" field. + // We support any field that Unmarshal can unmarshal tm into. + + inlinePtr := innerValue.FieldByIndex(inlineField.Index).Addr() + + // Copy all values that weren't non-inline fields into a temporary map. + // This is just to avoid mutating tm. + temp := NewMap[string, any](tm.Len()) + tm.Range(func(k string, v any) error { + if _, outline := outlineKeys[k]; outline { + return nil + } + temp.Set(k, v) + return nil + }) + + // If the inline map contains nothing, then don't bother setting it. + if temp.Len() == 0 { + return nil + } + + return Unmarshal(temp, inlinePtr.Interface()) +} + +// UnmarshalOrdered unmarshals a value into this map. +// K must be string, src must be *Map[string, any], and each value in src must +// be unmarshallable into *V. +func (m *Map[K, V]) UnmarshalOrdered(src any) error { + if m == nil { + return ErrIntoNil + } + + tm, ok := any(m).(*Map[string, V]) + if !ok { + return fmt.Errorf("%w: receiver type %T, want K = string", ErrIncompatibleTypes, m) + } + + tsrc, ok := src.(*Map[string, any]) + if !ok { + return fmt.Errorf("%w: src type %T, want *Map[string, any]", ErrIncompatibleTypes, src) + } + + return tsrc.Range(func(k string, v any) error { + var dv V + if err := Unmarshal(v, &dv); err != nil { + return err + } + tm.Set(k, dv) + return nil + }) +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/ordered/yaml.go b/vendor/github.com/buildkite/agent/v3/internal/ordered/yaml.go new file mode 100644 index 000000000..fd5b4b156 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/ordered/yaml.go @@ -0,0 +1,260 @@ +package ordered + +import ( + "fmt" + + "gopkg.in/yaml.v3" +) + +// DecodeYAML recursively unmarshals n into a generic type (any, []any, or +// *Map[string, any]) depending on the kind of n. Where yaml.v3 typically infer +// map[string]any for unmarshaling mappings into any, DecodeYAML chooses +// *Map[string, any] instead. +func DecodeYAML(n *yaml.Node) (any, error) { + return decodeYAML(make(map[*yaml.Node]bool), n) +} + +// decode recursively unmarshals n into a generic type (any, []any, or +// *Map[string, any]) depending on the kind of n. +func decodeYAML(seen map[*yaml.Node]bool, n *yaml.Node) (any, error) { + // nil decodes to nil. + if n == nil { + return nil, nil + } + + // If n has been seen already while processing the parents of n, it's an + // infinite recursion. + // Simple example: + // --- + // a: &a // seen is empty on encoding a + // b: *a // seen contains a while encoding b + if seen[n] { + return nil, fmt.Errorf("line %d, col %d: infinite recursion", n.Line, n.Column) + } + seen[n] = true + + // n needs to be "un-seen" when this layer of recursion is done: + defer delete(seen, n) + // Why? seen is a map, which is used by reference, so it will be shared + // between calls to decode, which is recursive. And unlike a merge, the + // same alias can be validly used for different subtrees: + // --- + // a: &a + // b: c + // d: + // da: *a + // db: *a + // ... + // (d contains two copies of a). + // So *a needs to be "unseen" between encoding "da" and "db". + + switch n.Kind { + case yaml.ScalarNode: + // If we need to parse more kinds of scalar, e.g. !!bool NO, or base-60 + // integers, this is where we would swap out n.Decode. + var v any + if err := n.Decode(&v); err != nil { + return nil, err + } + return v, nil + + case yaml.SequenceNode: + v := make([]any, 0, len(n.Content)) + for _, c := range n.Content { + cv, err := decodeYAML(seen, c) + if err != nil { + return nil, err + } + v = append(v, cv) + } + return v, nil + + case yaml.MappingNode: + m := NewMap[string, any](len(n.Content) / 2) + // Why not call m.UnmarshalYAML(n) ? + // Because we can't pass `seen` through that. + err := rangeYAMLMap(n, func(key string, val *yaml.Node) error { + v, err := decodeYAML(seen, val) + if err != nil { + return err + } + m.Set(key, v) + return nil + }) + if err != nil { + return nil, err + } + return m, nil + + case yaml.AliasNode: + // This is one of the two ways this can blow up recursively. + // The other (map merges) is handled by rangeMap. + return decodeYAML(seen, n.Alias) + + case yaml.DocumentNode: + switch len(n.Content) { + case 0: + return nil, nil + case 1: + return decodeYAML(seen, n.Content[0]) + default: + return nil, fmt.Errorf("line %d, col %d: document contains more than 1 content item (%d)", n.Line, n.Column, len(n.Content)) + } + + default: + return nil, fmt.Errorf("line %d, col %d: unsupported kind %x", n.Line, n.Column, n.Kind) + } +} + +// rangeYAMLMap calls f with each key/value pair in a mapping node. +// It only supports scalar keys, and converts them to canonical string values. +// Non-scalar and non-stringable keys result in an error. +// Because mapping nodes can contain merges from other mapping nodes, +// potentially via sequence nodes and aliases, this function also accepts +// sequences and aliases (that must themselves recursively only contain +// mappings, sequences, and aliases...). +func rangeYAMLMap(n *yaml.Node, f func(key string, val *yaml.Node) error) error { + return rangeYAMLMapImpl(make(map[*yaml.Node]bool), n, f) +} + +// rangeYAMLMapImpl implements rangeYAMLMap. It tracks mapping nodes already +// merged, to prevent infinite merge loops and avoid unnecessarily merging the +// same mapping repeatedly. +func rangeYAMLMapImpl(merged map[*yaml.Node]bool, n *yaml.Node, f func(key string, val *yaml.Node) error) error { + // Go-like semantics: no entries in "nil". + if n == nil { + return nil + } + + // If this node has already been merged into the top-level map being ranged, + // we don't need to merge it again. + if merged[n] { + return nil + } + merged[n] = true + + switch n.Kind { + case yaml.MappingNode: + // gopkg.in/yaml.v3 parses mapping node contents as a flat list: + // key, value, key, value... + if len(n.Content)%2 != 0 { + return fmt.Errorf("line %d, col %d: mapping node has odd content length %d", n.Line, n.Column, len(n.Content)) + } + + // Keys at an outer level take precedence over keys being merged: + // "its key/value pairs is inserted into the current mapping, unless the + // key already exists in it." https://yaml.org/type/merge.html + // But we care about key ordering! + // This necessitates two passes: + // 1. Obtain the keys in this map + // 2. Range over the map again, recursing into merges. + // While merging, ignore keys in the outer level. + // Merges may produce new keys to ignore in subsequent merges: + // "Keys in mapping nodes earlier in the sequence override keys + // specified in later mapping nodes." + + // 1. A pass to get the keys at this level. + keys := make(map[string]bool) + for i := 0; i < len(n.Content); i += 2 { + k := n.Content[i] + + // Ignore merges in this pass. + if k.Tag == "!!merge" { + continue + } + + // Canonicalise the key into a string and store it. + ck, err := canonicalMapKey(k) + if err != nil { + return err + } + keys[ck] = true + } + + // Ignore existing keys when merging. Record new keys to ignore in + // subsequent merges. + skipKeys := func(k string, v *yaml.Node) error { + if keys[k] { + return nil + } + keys[k] = true + return f(k, v) + } + + // 2. Range over each pair, recursing into merges. + for i := 0; i < len(n.Content); i += 2 { + k, v := n.Content[i], n.Content[i+1] + + // Is this pair a merge? (`<<: *foo`) + if k.Tag == "!!merge" { + // Recursively range over the contents of the value, which + // could be an alias to a mapping node, or a sequence of aliases + // to mapping nodes, which could themselves contain merges... + if err := rangeYAMLMapImpl(merged, v, skipKeys); err != nil { + return err + } + continue + } + + // Canonicalise the key into a string (again). + ck, err := canonicalMapKey(k) + if err != nil { + return err + } + + // Yield the canonical key and the value. + if err := f(ck, v); err != nil { + return err + } + } + + case yaml.SequenceNode: + // Range over each element e in the sequence. + for _, e := range n.Content { + if err := rangeYAMLMapImpl(merged, e, f); err != nil { + return err + } + } + + case yaml.AliasNode: + // Follow the alias and range over that. + if err := rangeYAMLMapImpl(merged, n.Alias, f); err != nil { + return err + } + + default: + // TODO: Use %v once yaml.Kind has a String method + return fmt.Errorf("line %d, col %d: cannot range over node kind %x", n.Line, n.Column, n.Kind) + } + return nil +} + +// canonicalMapKey converts a scalar value into a string suitable for use as +// a map key. YAML expects different representations of the same value, e.g. +// 0xb and 11, to be equivalent, and therefore a duplicate key. JSON requires +// all keys to be strings. +func canonicalMapKey(n *yaml.Node) (string, error) { + var x any + if err := n.Decode(&x); err != nil { + return "", err + } + if x == nil || n.Tag == "!!null" { + // Nulls are not valid JSON keys. + return "", fmt.Errorf("line %d, col %d: null not supported as a map key", n.Line, n.Column) + } + switch n.Tag { + case "!!bool": + // Canonicalise to true or false. + return fmt.Sprintf("%t", x), nil + case "!!int": + // Canonicalise to decimal. + return fmt.Sprintf("%d", x), nil + case "!!float": + // Canonicalise to scientific notation. + // Don't handle Inf or NaN specially, as they will be quoted. + return fmt.Sprintf("%e", x), nil + default: + // Assume the value is already a suitable key. + return n.Value, nil + } +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/doc.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/doc.go new file mode 100644 index 000000000..28f933594 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/doc.go @@ -0,0 +1,13 @@ +// Package pipeline implements the pieces necessary for the agent to work with +// pipelines (typically in YAML or JSON form). +// +// The pipeline object model (Pipeline, Steps, Plugin, etc) have these caveats: +// - It is incomplete: there may be fields accepted by the API that are not +// listed. Do not treat Pipeline, CommandStep, etc, as comprehensive +// reference guides for how to write a pipeline. +// - It normalises: unmarshaling accepts a variety of step forms, but +// marshaling back out produces more normalised output. An unmarshal/marshal +// round-trip may produce different output. +// - It is non-canonical: using the object model does not guarantee that a +// pipeline will be accepted by the pipeline upload API. +package pipeline diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/interpolate.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/interpolate.go new file mode 100644 index 000000000..199e16433 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/interpolate.go @@ -0,0 +1,161 @@ +package pipeline + +import ( + "github.com/buildkite/agent/v3/internal/ordered" + "github.com/buildkite/interpolate" +) + +// This file contains helpers for recursively interpolating all the strings in +// pipeline objects. + +// stringTransformer implementations mutate strings. +type stringTransformer interface { + Transform(string) (string, error) +} + +// envInterpolator returns a reusable string transform that replaces +// variables (${FOO}) with their values from a map. +type envInterpolator struct { + envMap interpolate.Env +} + +// Transform calls interpolate.Interpolate to transform the string. +func (e envInterpolator) Transform(s string) (string, error) { + return interpolate.Interpolate(e.envMap, s) +} + +// selfInterpolater describes types that can interpolate themselves in-place. +// They can use the string transformer on string fields, or use +// interpolate{Slice,Map,OrderedMap,Any} on their other contents, to do this. +type selfInterpolater interface { + interpolate(stringTransformer) error +} + +// interpolateAny interpolates (almost) anything in-place. When passed a string, +// it returns a new string. Anything it doesn't know how to interpolate is +// returned unaltered. +func interpolateAny[T any](tf stringTransformer, o T) (T, error) { + // The box-typeswitch-unbox dance is required because the Go compiler + // has no type switch for type parameters. + var err error + a := any(o) + + switch t := a.(type) { + case selfInterpolater: + err = t.interpolate(tf) + + case *string: + if t == nil { + return o, nil + } + *t, err = tf.Transform(*t) + a = t + + case string: + a, err = tf.Transform(t) + + case []any: + err = interpolateSlice(tf, t) + + case []string: + err = interpolateSlice(tf, t) + + case ordered.Slice: + err = interpolateSlice(tf, t) + + case map[string]any: + err = interpolateMap(tf, t) + + case map[string]string: + err = interpolateMap(tf, t) + + case *ordered.Map[string, any]: + err = interpolateOrderedMap(tf, t) + + case *ordered.Map[string, string]: + err = interpolateOrderedMap(tf, t) + + default: + return o, nil + } + + // This happens if T is an interface type and o was interface-nil to begin + // with. (You can't type assert interface-nil.) + if a == nil { + var zt T + return zt, err + } + return a.(T), err +} + +// interpolateSlice applies interpolateAny over any type of slice. Values in the +// slice are updated in-place. +func interpolateSlice[E any, S ~[]E](tf stringTransformer, s S) error { + for i, e := range s { + // It could be a string, so replace the old value with the new. + inte, err := interpolateAny(tf, e) + if err != nil { + return err + } + s[i] = inte + } + return nil +} + +// interpolateMapValues applies interpolateAny over the values of any type of +// map. The map is altered in-place. +func interpolateMapValues[K comparable, V any, M ~map[K]V](tf stringTransformer, m M) error { + for k, v := range m { + // V could be string, so be sure to replace the old value with the new. + intv, err := interpolateAny(tf, v) + if err != nil { + return err + } + m[k] = intv + } + return nil +} + +// interpolateMap applies interpolateAny over both keys and values of any type +// of map. The map is altered in-place. +func interpolateMap[K comparable, V any, M ~map[K]V](tf stringTransformer, m M) error { + for k, v := range m { + // We interpolate both keys and values. + intk, err := interpolateAny(tf, k) + if err != nil { + return err + } + + // V could be string, so be sure to replace the old value with the new. + intv, err := interpolateAny(tf, v) + if err != nil { + return err + } + + // If the key changed due to interpolation, delete the old key. + if k != intk { + delete(m, k) + } + m[intk] = intv + } + return nil +} + +// interpolateOrderedMap applies interpolateAny over any type of ordered.Map. +// The map is altered in-place. +func interpolateOrderedMap[K comparable, V any](tf stringTransformer, m *ordered.Map[K, V]) error { + return m.Range(func(k K, v V) error { + // We interpolate both keys and values. + intk, err := interpolateAny(tf, k) + if err != nil { + return err + } + intv, err := interpolateAny(tf, v) + if err != nil { + return err + } + + m.Replace(k, intk, intv) + return nil + }) +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/interpolate_matrix.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/interpolate_matrix.go new file mode 100644 index 000000000..f420db6a5 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/interpolate_matrix.go @@ -0,0 +1,55 @@ +package pipeline + +import ( + "fmt" + "regexp" + "strings" +) + +// Match double curly bois containing any whitespace, "matrix", then maybe +// a dot and a dimension name, ending with any whitespace and closing curlies. +var matrixTokenRE = regexp.MustCompile(`\{\{\s*matrix(\.[\w-\.]+)?\s*\}\}`) + +// matrixInterpolator is a string transform that interpolates matrix tokens. +type matrixInterpolator struct { + replacements map[string]string +} + +// Transform interpolates matrix tokens. +func (m matrixInterpolator) Transform(src string) (string, error) { + var unknown []string + + out := matrixTokenRE.ReplaceAllStringFunc(src, func(s string) string { + sub := matrixTokenRE.FindStringSubmatch(s) + repl, ok := m.replacements[sub[1]] + if !ok { + unknown = append(unknown, sub[1]) + } + return repl + }) + + if len(unknown) > 0 { + for i, f := range unknown { + unknown[i] = "matrix" + f + } + return out, fmt.Errorf("unknown matrix tokens in input: %s", strings.Join(unknown, ", ")) + } + return out, nil +} + +// newMatrixInterpolator creates a reusable string transformer that applies +// matrix interpolation. +func newMatrixInterpolator(mp MatrixPermutation) matrixInterpolator { + replacements := make(map[string]string) + for dim, val := range mp { + if dim == "" { + replacements[""] = val + } else { + replacements["."+dim] = val + } + } + + return matrixInterpolator{ + replacements: replacements, + } +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/json.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/json.go new file mode 100644 index 000000000..a28a02e3e --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/json.go @@ -0,0 +1,98 @@ +package pipeline + +import ( + "encoding/json" + "fmt" + "reflect" + "strings" + + "github.com/oleiade/reflections" +) + +// inlineFriendlyMarshalJSON marshals the given object to JSON, but with special handling given to fields tagged with ",inline". +// This is needed because yaml.v3 has "inline" but encoding/json has no concept of it. +func inlineFriendlyMarshalJSON(q any) ([]byte, error) { + fieldNames, err := reflections.Fields(q) + if err != nil { + return nil, fmt.Errorf("could not get fields of %T: %w", q, err) + } + + var inlineFields map[string]any // no need to pre-allocate, we directly set it if we find inline fields + outlineFields := make(map[string]any, len(fieldNames)) + + for _, fieldName := range fieldNames { + tag, err := reflections.GetFieldTag(q, fieldName, "yaml") + if err != nil { + return nil, fmt.Errorf("could not get yaml tag of %T.%s: %w", q, fieldName, err) + } + + switch tag { + case "-": + continue + + case ",inline": + inlineFieldsValue, err := reflections.GetField(q, fieldName) + if err != nil { + return nil, fmt.Errorf("could not get inline fields value of %T.%s: %w", q, fieldName, err) + } + + if inf, ok := inlineFieldsValue.(map[string]any); ok { + inlineFields = inf + } else { + return nil, fmt.Errorf("inline fields value of %T.%s must be a map[string]any, was %T instead", q, fieldName, inlineFieldsValue) + } + + default: + fieldValue, err := reflections.GetField(q, fieldName) + if err != nil { + return nil, fmt.Errorf("could not get value of %T.%s: %w", q, fieldName, err) + } + + tags := strings.Split(tag, ",") + keyName := tags[0] // e.g. "foo,omitempty" -> "foo" + if len(tags) > 1 && tags[1] == "omitempty" && isEmptyValue(fieldValue) { + continue + } + + outlineFields[keyName] = fieldValue + } + } + + allFields := make(map[string]any, len(outlineFields)+len(inlineFields)) + + for k, v := range inlineFields { + allFields[k] = v + } + + // "outline" (non-inline) fields should take precedence over inline fields + for k, v := range outlineFields { + allFields[k] = v + } + + return json.Marshal(allFields) +} + +// stolen from encoding/json +func isEmptyValue(q any) bool { + if q == nil { // not stolen from encoding/json, but oddly missing from it? + return true + } + + v := reflect.ValueOf(q) + + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Pointer: + return v.IsNil() + } + return false +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/parser.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/parser.go new file mode 100644 index 000000000..b8b3334e6 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/parser.go @@ -0,0 +1,32 @@ +package pipeline + +import ( + "errors" + "io" + "strings" + + "github.com/buildkite/agent/v3/internal/ordered" + "gopkg.in/yaml.v3" +) + +// Parse parses a pipeline. It does not apply interpolation. +func Parse(src io.Reader) (*Pipeline, error) { + // First get yaml.v3 to give us a raw document (*yaml.Node). + n := new(yaml.Node) + if err := yaml.NewDecoder(src).Decode(n); err != nil { + return nil, formatYAMLError(err) + } + + // Instead of unmarshalling into structs, which is easy-ish to use but + // doesn't work with some non YAML 1.2 features (merges), decode the + // *yaml.Node into *ordered.Map, []any, or any (recursively). + // This resolves aliases and merges and gives a more convenient form to work + // with when handling different structural representations of the same + // configuration. Then decode _that_ into a pipeline. + p := new(Pipeline) + return p, ordered.Unmarshal(n, p) +} + +func formatYAMLError(err error) error { + return errors.New(strings.TrimPrefix(err.Error(), "yaml: ")) +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/pipeline.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/pipeline.go new file mode 100644 index 000000000..ae4e15599 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/pipeline.go @@ -0,0 +1,131 @@ +package pipeline + +import ( + "fmt" + + "github.com/buildkite/agent/v3/env" + "github.com/buildkite/agent/v3/internal/ordered" + "github.com/buildkite/agent/v3/tracetools" + "github.com/buildkite/interpolate" + "github.com/lestrrat-go/jwx/v2/jwk" +) + +// Pipeline models a pipeline. +// +// Standard caveats apply - see the package comment. +type Pipeline struct { + Steps Steps `yaml:"steps"` + Env *ordered.MapSS `yaml:"env,omitempty"` + + // RemainingFields stores any other top-level mapping items so they at least + // survive an unmarshal-marshal round-trip. + RemainingFields map[string]any `yaml:",inline"` +} + +// MarshalJSON marshals a pipeline to JSON. Special handling is needed because +// yaml.v3 has "inline" but encoding/json has no concept of it. +func (p *Pipeline) MarshalJSON() ([]byte, error) { + return inlineFriendlyMarshalJSON(p) +} + +// UnmarshalOrdered unmarshals the pipeline from either []any (a legacy +// sequence of steps) or *ordered.MapSA (a modern pipeline configuration). +func (p *Pipeline) UnmarshalOrdered(o any) error { + switch o := o.(type) { + case *ordered.MapSA: + // A pipeline can be a mapping. + // Wrap in a secret type to avoid infinite recursion between this method + // and ordered.Unmarshal. + type wrappedPipeline Pipeline + if err := ordered.Unmarshal(o, (*wrappedPipeline)(p)); err != nil { + return fmt.Errorf("unmarshaling Pipeline: %w", err) + } + + case []any: + // A pipeline can be a sequence of steps. + if err := ordered.Unmarshal(o, &p.Steps); err != nil { + return fmt.Errorf("unmarshaling steps: %w", err) + } + + default: + return fmt.Errorf("unmarshaling Pipeline: unsupported type %T, want either *ordered.Map[string, any] or []any", o) + } + + // Ensure Steps is never nil. Server side expects a sequence. + if p.Steps == nil { + p.Steps = Steps{} + } + return nil +} + +// Interpolate interpolates variables defined in both envMap and p.Env into the +// pipeline. +// More specifically, it does these things: +// - Copy tracing context keys from envMap into pipeline.Env. +// - Interpolate pipeline.Env and copy the results into envMap to apply later. +// - Interpolate any string value in the rest of the pipeline. +func (p *Pipeline) Interpolate(envMap *env.Environment) error { + if envMap == nil { + envMap = env.New() + } + + // Propagate distributed tracing context to the new pipelines if available + if tracing, has := envMap.Get(tracetools.EnvVarTraceContextKey); has { + if p.Env == nil { + p.Env = ordered.NewMap[string, string](1) + } + p.Env.Set(tracetools.EnvVarTraceContextKey, tracing) + } + + // Preprocess any env that are defined in the top level block and place them + // into env for later interpolation into the rest of the pipeline. + if err := p.interpolateEnvBlock(envMap); err != nil { + return err + } + + tf := envInterpolator{envMap: envMap} + + // Recursively go through the rest of the pipeline and perform environment + // variable interpolation on strings. Interpolation is performed in-place. + if err := interpolateSlice(tf, p.Steps); err != nil { + return err + } + return interpolateMap(tf, p.RemainingFields) +} + +// interpolateEnvBlock runs interpolate.Interpolate on each pair in p.Env, +// interpolating with the variables defined in envMap, and then adding the +// results back into both p.Env and envMap. Each environment variable can +// be interpolated into later environment variables, making the input ordering +// of p.Env potentially important. +func (p *Pipeline) interpolateEnvBlock(envMap *env.Environment) error { + return p.Env.Range(func(k, v string) error { + // We interpolate both keys and values. + intk, err := interpolate.Interpolate(envMap, k) + if err != nil { + return err + } + + // v is always a string in this case. + intv, err := interpolate.Interpolate(envMap, v) + if err != nil { + return err + } + + p.Env.Replace(k, intk, intv) + + // Bonus part for the env block! + // Add the results back into envMap. + envMap.Set(intk, intv) + return nil + }) +} + +// Sign signs each signable part of the pipeline. Currently this is limited to +// command steps (including command steps within group steps), including all +// plugin configurations and the pipeline "env". Parts of the pipeline are +// mutated directly, so an error part-way through may leave some steps +// un-signed. +func (p *Pipeline) Sign(key jwk.Key, inv *PipelineInvariants) error { + return p.Steps.sign(key, p.Env.ToMap(), inv) +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/pipeline_invariants.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/pipeline_invariants.go new file mode 100644 index 000000000..2ccf2a4b2 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/pipeline_invariants.go @@ -0,0 +1,82 @@ +package pipeline + +import ( + "fmt" + "strings" +) + +type PipelineInvariants struct { + OrganizationSlug string + PipelineSlug string + Repository string +} + +var _ SignedFielder = (*CommandStepWithPipelineInvariants)(nil) + +type CommandStepWithPipelineInvariants struct { + CommandStep + PipelineInvariants +} + +// SignedFields returns the default fields for signing. +func (c *CommandStepWithPipelineInvariants) SignedFields() (map[string]any, error) { + return map[string]any{ + "command": c.Command, + "env": c.Env, + "plugins": c.Plugins, + "matrix": c.Matrix, + "pipeline_invariants": c.PipelineInvariants, + }, nil +} + +// ValuesForFields returns the contents of fields to sign. +func (c *CommandStepWithPipelineInvariants) ValuesForFields(fields []string) (map[string]any, error) { + // Make a set of required fields. As fields is processed, mark them off by + // deleting them. + required := map[string]struct{}{ + "command": {}, + "env": {}, + "plugins": {}, + "matrix": {}, + "pipeline_invariants": {}, + } + + out := make(map[string]any, len(fields)) + for _, f := range fields { + delete(required, f) + + switch f { + case "command": + out["command"] = c.Command + + case "env": + out["env"] = c.Env + + case "plugins": + out["plugins"] = c.Plugins + + case "matrix": + out["matrix"] = c.Matrix + + case "pipeline_invariants": + out["pipeline_invariants"] = c.PipelineInvariants + + default: + // All env:: values come from outside the step. + if strings.HasPrefix(f, EnvNamespacePrefix) { + break + } + + return nil, fmt.Errorf("unknown or unsupported field for signing %q", f) + } + } + + if len(required) > 0 { + missing := make([]string, 0, len(required)) + for k := range required { + missing = append(missing, k) + } + return nil, fmt.Errorf("one or more required fields are not present: %v", missing) + } + return out, nil +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/plugin.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/plugin.go new file mode 100644 index 000000000..670c52902 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/plugin.go @@ -0,0 +1,112 @@ +package pipeline + +import ( + "encoding/json" + "net/url" + "path" + "strings" + + "gopkg.in/yaml.v3" +) + +var ( + _ interface { + json.Marshaler + yaml.Marshaler + selfInterpolater + } = (*Plugin)(nil) +) + +// Plugin models plugin configuration. +// +// Standard caveats apply - see the package comment. +type Plugin struct { + Source string + Config any +} + +// MarshalJSON returns the plugin in "one-key object" form, or "single string" +// form (no config, only plugin source). Plugin sources are marshalled into "full" +// form. +func (p *Plugin) MarshalJSON() ([]byte, error) { + // NB: MarshalYAML (as seen below) never returns an error. + o, _ := p.MarshalYAML() + return json.Marshal(o) +} + +// MarshalYAML returns the plugin in either "one-item map" form, or "scalar" +// form (no config, only plugin source). Plugin sources are marshalled into "full" +// form. +func (p *Plugin) MarshalYAML() (any, error) { + if p.Config == nil { + return p.FullSource(), nil + } + + return map[string]any{ + p.FullSource(): p.Config, + }, nil +} + +// FullSource attempts to canonicalise Source. If it fails, it returns Source +// unaltered. Otherwise, it resolves sources in a manner described at +// https://buildkite.com/docs/plugins/using#plugin-sources. +func (p *Plugin) FullSource() string { + if p.Source == "" { + return "" + } + + // Looks like an absolute or relative file path. + if strings.HasPrefix(p.Source, "/") || strings.HasPrefix(p.Source, ".") || strings.HasPrefix(p.Source, `\`) { + return p.Source + } + + u, err := url.Parse(p.Source) + if err != nil { + return p.Source + } + + // They wrote something like ssh://..., https://..., or C:\... + // in which case they _mean it_. + if u.Scheme != "" || u.Opaque != "" { + return p.Source + } + + // thing => thing-buildkite-plugin + // thing#main => thing-buildkite-plugin#main + lastSegment := func(n, f string) string { + n += "-buildkite-plugin" + if f == "" { + return n + } + return n + "#" + f + } + + paths := strings.Split(strings.TrimPrefix(u.Path, "/"), "/") + switch len(paths) { + case 1: + // trimmed path contained no slash + return path.Join("github.com", "buildkite-plugins", lastSegment(paths[0], u.Fragment)) + + case 2: + // trimmed path contained one slash + return path.Join("github.com", paths[0], lastSegment(paths[1], u.Fragment)) + + default: + // trimmed path contained more than one slash - apply no smarts + return p.Source + } +} + +func (p *Plugin) interpolate(tf stringTransformer) error { + name, err := tf.Transform(p.Source) + if err != nil { + return err + } + cfg, err := interpolateAny(tf, p.Config) + if err != nil { + return err + } + p.Source = name + p.Config = cfg + return nil +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/plugins.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/plugins.go new file mode 100644 index 000000000..790cd595f --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/plugins.go @@ -0,0 +1,106 @@ +package pipeline + +import ( + "encoding/json" + "fmt" + + "github.com/buildkite/agent/v3/internal/ordered" + "gopkg.in/yaml.v3" +) + +var _ interface { + json.Unmarshaler + ordered.Unmarshaler +} = (*Plugins)(nil) + +// Plugins is a sequence of plugins. It is useful for unmarshaling. +type Plugins []*Plugin + +// UnmarshalOrdered unmarshals Plugins from either +// - []any - originally a sequence of "one-item mappings" (normal form), or +// - *ordered.MapSA - a mapping (where order is important...non-normal form). +// +// "plugins" is supposed to be a sequence of one-item maps, since order matters. +// But some people (even us) write plugins into one big mapping and rely on +// order preservation. +func (p *Plugins) UnmarshalOrdered(o any) error { + // Whether processing one big map, or a sequence of small maps, the central + // part remains the same. + // Parse each "key: value" as "name: config", then append in order. + unmarshalMap := func(m *ordered.MapSA) error { + return m.Range(func(k string, v any) error { + // ToMapRecursive demolishes any ordering within the plugin config. + // This is needed because the backend likes to reorder the keys, + // and for signing we need the JSON form to be stable. + plugin := &Plugin{ + Source: k, + Config: ordered.ToMapRecursive(v), + } + *p = append(*p, plugin) + return nil + }) + } + + switch o := o.(type) { + case nil: + // Someone wrote `plugins: null` (possibly us). + *p = nil + return nil + + case []any: + for _, c := range o { + switch ct := c.(type) { + case *ordered.MapSA: + // Typical case: + // + // plugins: + // - plugin#1.0.0: + // config: config, etc + if err := unmarshalMap(ct); err != nil { + return err + } + + case string: + // Less typical, but supported: + // + // plugins: + // - plugin#1.0.0 + // (no config, only plugin) + *p = append(*p, &Plugin{ + Source: ct, + Config: nil, + }) + + default: + return fmt.Errorf("unmarshaling plugins: plugin type %T, want *ordered.Map[string, any] or string", c) + } + } + + case *ordered.MapSA: + // Legacy form: + // + // plugins: + // plugin#1.0.0: + // config: config, etc + // otherplugin#2.0.0: + // etc + if err := unmarshalMap(o); err != nil { + return err + } + + default: + return fmt.Errorf("unmarshaling plugins: got %T, want []any or *ordered.Map[string, any]", o) + + } + return nil +} + +// UnmarshalJSON is used mainly to normalise the BUILDKITE_PLUGINS env var. +func (p *Plugins) UnmarshalJSON(b []byte) error { + // JSON is just a specific kind of YAML. + var n yaml.Node + if err := yaml.Unmarshal(b, &n); err != nil { + return err + } + return ordered.Unmarshal(&n, &p) +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/sign.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/sign.go new file mode 100644 index 000000000..6f26356f8 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/sign.go @@ -0,0 +1,185 @@ +package pipeline + +import ( + "encoding/json" + "errors" + "fmt" + "sort" + + "github.com/gowebpki/jcs" + "github.com/lestrrat-go/jwx/v2/jwk" + "github.com/lestrrat-go/jwx/v2/jws" +) + +// EnvNamespacePrefix is the string that prefixes all fields in the "env" +// namespace. This is used to separate signed data that came from the +// environment from data that came from an object. +const EnvNamespacePrefix = "env::" + +// Signature models a signature (on a step, etc). +type Signature struct { + Algorithm string `json:"algorithm" yaml:"algorithm"` + SignedFields []string `json:"signed_fields" yaml:"signed_fields"` + Value string `json:"value" yaml:"value"` +} + +// SignedFielder describes types that can be signed and have signatures +// verified. +// Converting non-string fields into strings (in a stable, canonical way) is an +// exercise left to the implementer. +type SignedFielder interface { + // SignedFields returns the default set of fields to sign, and their values. + // This is called by Sign. + SignedFields() (map[string]any, error) + + // ValuesForFields looks up each field and produces a map of values. This is + // called by Verify. The set of fields might differ from the default, e.g. + // when verifying older signatures computed with fewer fields or deprecated + // field names. signedFielder implementations should reject requests for + // values if "mandatory" fields are missing (e.g. signing a command step + // should always sign the command). + ValuesForFields([]string) (map[string]any, error) +} + +// Sign computes a new signature for an environment (env) combined with an +// object containing values (sf) using a given key. +func Sign( + key jwk.Key, + env map[string]string, + sf SignedFielder, +) (*Signature, error) { + values, err := sf.SignedFields() + if err != nil { + return nil, err + } + if len(values) == 0 { + return nil, errors.New("no fields to sign") + } + + // Step env overrides pipeline and build env: + // https://buildkite.com/docs/tutorials/pipeline-upgrade#what-is-the-yaml-steps-editor-compatibility-issues + // (Beware of inconsistent docs written in the time of legacy steps.) + // So if the thing we're signing has an env map, use it to exclude pipeline + // vars from signing. + objEnv, _ := values["env"].(map[string]string) + + // Namespace the env values and include them in the values to sign. + for k, v := range env { + if _, has := objEnv[k]; has { + continue + } + values[EnvNamespacePrefix+k] = v + } + + // Extract the names of the fields. + fields := make([]string, 0, len(values)) + for field := range values { + fields = append(fields, field) + } + sort.Strings(fields) + + payload, err := canonicalPayload(key.Algorithm().String(), values) + if err != nil { + return nil, err + } + + sig, err := jws.Sign(nil, + jws.WithKey(key.Algorithm(), key), + jws.WithDetachedPayload(payload), + jws.WithCompact(), + ) + if err != nil { + return nil, err + } + + return &Signature{ + Algorithm: key.Algorithm().String(), + SignedFields: fields, + Value: string(sig), + }, nil +} + +// Verify verifies an existing signature against environment (env) combined with +// an object containing values (sf) using keys from a keySet. +func (s *Signature) Verify( + keySet jwk.Set, + env map[string]string, + sf SignedFielder, +) error { + if len(s.SignedFields) == 0 { + return errors.New("signature covers no fields") + } + + // Ask the object for values for all fields. + values, err := sf.ValuesForFields(s.SignedFields) + if err != nil { + return fmt.Errorf("obtaining values for fields: %w", err) + } + + // See Sign above for why we need special handling for step env. + objEnv, _ := values["env"].(map[string]string) + + // Namespace the env values and include them in the values to sign. + for k, v := range env { + if _, has := objEnv[k]; has { + continue + } + values[EnvNamespacePrefix+k] = v + } + + // env:: fields that were signed are all required from the env map. + // We can't verify other env vars though - they can vary for lots of reasons + // (e.g. Buildkite-provided vars added by the backend.) + // This is still strong enough for a user to enforce any particular env var + // exists and has a particular value - make it a part of the pipeline or + // step env. + required, err := requireKeys(values, s.SignedFields) + if err != nil { + return fmt.Errorf("obtaining required keys: %w", err) + } + + payload, err := canonicalPayload(s.Algorithm, required) + if err != nil { + return err + } + + _, err = jws.Verify([]byte(s.Value), + jws.WithKeySet(keySet), + jws.WithDetachedPayload(payload), + ) + return err +} + +// canonicalPayload returns a unique sequence of bytes representing the given +// algorithm and values using JCS (RFC 8785). +func canonicalPayload(alg string, values map[string]any) ([]byte, error) { + rawPayload, err := json.Marshal(struct { + Algorithm string `json:"alg"` + Values map[string]any `json:"values"` + }{ + Algorithm: alg, + Values: values, + }) + if err != nil { + return nil, fmt.Errorf("marshaling JSON: %w", err) + } + payload, err := jcs.Transform(rawPayload) + if err != nil { + return nil, fmt.Errorf("canonicalising JSON: %w", err) + } + return payload, nil +} + +// requireKeys returns a copy of a map containing only keys from a []string. +// An error is returned if any keys are missing from the map. +func requireKeys[K comparable, V any, M ~map[K]V](in M, keys []K) (M, error) { + out := make(M, len(keys)) + for _, k := range keys { + v, ok := in[k] + if !ok { + return nil, fmt.Errorf("missing key %v", k) + } + out[k] = v + } + return out, nil +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/step.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step.go new file mode 100644 index 000000000..0c1e44d73 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step.go @@ -0,0 +1,13 @@ +package pipeline + +// Step models a step in the pipeline. It will be a pointer to one of: +// - CommandStep +// - WaitStep +// - InputStep +// - TriggerStep +// - GroupStep +type Step interface { + stepTag() // allow only the step types below + + selfInterpolater +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_command.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_command.go new file mode 100644 index 000000000..40b5c42c6 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_command.go @@ -0,0 +1,125 @@ +package pipeline + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/buildkite/agent/v3/internal/ordered" + "gopkg.in/yaml.v3" +) + +var _ interface { + json.Marshaler + json.Unmarshaler + ordered.Unmarshaler +} = (*CommandStep)(nil) + +// CommandStep models a command step. +// +// Standard caveats apply - see the package comment. +type CommandStep struct { + Command string `yaml:"command"` + Plugins Plugins `yaml:"plugins,omitempty"` + Env map[string]string `yaml:"env,omitempty"` + Signature *Signature `yaml:"signature,omitempty"` + Matrix *Matrix `yaml:"matrix,omitempty"` + + // RemainingFields stores any other top-level mapping items so they at least + // survive an unmarshal-marshal round-trip. + RemainingFields map[string]any `yaml:",inline"` +} + +// MarshalJSON marshals the step to JSON. Special handling is needed because +// yaml.v3 has "inline" but encoding/json has no concept of it. +func (c *CommandStep) MarshalJSON() ([]byte, error) { + return inlineFriendlyMarshalJSON(c) +} + +// UnmarshalJSON is used when unmarshalling an individual step directly, e.g. +// from the Agent API Accept Job. +func (c *CommandStep) UnmarshalJSON(b []byte) error { + // JSON is just a specific kind of YAML. + var n yaml.Node + if err := yaml.Unmarshal(b, &n); err != nil { + return err + } + return ordered.Unmarshal(&n, &c) +} + +// UnmarshalOrdered unmarshals a command step from an ordered map. +func (c *CommandStep) UnmarshalOrdered(src any) error { + type wrappedCommand CommandStep + // Unmarshal into this secret type, then process special fields specially. + fullCommand := new(struct { + Command []string `yaml:"command"` + Commands []string `yaml:"commands"` + + // Use inline trickery to capture the rest of the struct. + Rem *wrappedCommand `yaml:",inline"` + }) + fullCommand.Rem = (*wrappedCommand)(c) + if err := ordered.Unmarshal(src, fullCommand); err != nil { + return fmt.Errorf("unmarshalling CommandStep: %w", err) + } + + // Normalise cmds into one single command string. + // This makes signing easier later on - it's easier to hash one + // string consistently than it is to pick apart multiple strings + // in a consistent way in order to hash all of them + // consistently. + cmds := append(fullCommand.Command, fullCommand.Commands...) + c.Command = strings.Join(cmds, "\n") + return nil +} + +// InterpolateMatrixPermutation validates and then interpolates the choice of +// matrix values into the step. This should only be used in order to validate +// a job that's about to be run, and not used before pipeline upload. +func (c *CommandStep) InterpolateMatrixPermutation(mp MatrixPermutation) error { + if err := c.Matrix.validatePermutation(mp); err != nil { + return err + } + if len(mp) == 0 { + return nil + } + return c.interpolate(newMatrixInterpolator(mp)) +} + +func (c *CommandStep) interpolate(tf stringTransformer) error { + cmd, err := tf.Transform(c.Command) + if err != nil { + return err + } + c.Command = cmd + + if err := interpolateSlice(tf, c.Plugins); err != nil { + return err + } + + switch tf.(type) { + case envInterpolator: + if err := interpolateMap(tf, c.Env); err != nil { + return err + } + if c.Matrix, err = interpolateAny(tf, c.Matrix); err != nil { + return err + } + + case matrixInterpolator: + // Matrix interpolation doesn't apply to env keys. + if err := interpolateMapValues(tf, c.Env); err != nil { + return err + } + } + + // NB: Do not interpolate Signature. + + if err := interpolateMap(tf, c.RemainingFields); err != nil { + return err + } + + return nil +} + +func (CommandStep) stepTag() {} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_command_matrix.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_command_matrix.go new file mode 100644 index 000000000..a37c12ce7 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_command_matrix.go @@ -0,0 +1,365 @@ +package pipeline + +import ( + "encoding/json" + "errors" + "fmt" + + "github.com/buildkite/agent/v3/internal/ordered" + "gopkg.in/yaml.v3" +) + +var ( + _ interface { + json.Marshaler + ordered.Unmarshaler + yaml.Marshaler + selfInterpolater + } = (*Matrix)(nil) + + _ interface { + json.Marshaler + selfInterpolater + } = (*MatrixAdjustment)(nil) + + _ = []interface { + json.Marshaler + ordered.Unmarshaler + yaml.Marshaler + }{ + (*MatrixSetup)(nil), + (*MatrixAdjustmentWith)(nil), + } +) + +var ( + errNilMatrix = errors.New("non-empty permutation but matrix is nil") + errPermutationLengthMismatch = errors.New("permutation has wrong length") + errPermutationUnknownDimension = errors.New("permutation has unknown dimension") + errAdjustmentLengthMismatch = errors.New("adjustment has wrong length") + errAdjustmentUnknownDimension = errors.New("adjustment has unknown dimension") + errPermutationSkipped = errors.New("permutation is skipped by adjustment") + errPermutationNoMatch = errors.New("permutation is neither a valid matrix combination nor an adjustment") +) + +// Matrix models the matrix specification for command steps. +type Matrix struct { + Setup MatrixSetup `yaml:"setup"` + Adjustments MatrixAdjustments `yaml:"adjustments,omitempty"` + + RemainingFields map[string]any `yaml:",inline"` +} + +// UnmarshalOrdererd unmarshals from either []any or *ordered.MapSA. +func (m *Matrix) UnmarshalOrdered(o any) error { + switch src := o.(type) { + case []any: + // Single anonymous dimension matrix, no adjustments. + // + // matrix: + // - apple + // - 47 + s := make([]string, 0, len(src)) + if err := ordered.Unmarshal(src, &s); err != nil { + return err + } + m.Setup = MatrixSetup{"": s} + + case *ordered.MapSA: + // Single anonymous dimension, or multiple named dimensions, with or + // without adjustments. + // Unmarshal into this secret wrapper type to avoid infinite recursion. + type wrappedMatrix Matrix + if err := ordered.Unmarshal(o, (*wrappedMatrix)(m)); err != nil { + return err + } + + default: + return fmt.Errorf("unsupported src type for Matrix: %T", o) + } + return nil +} + +// Reports if the matrix is a single anonymous dimension matrix with no +// adjustments or any other fields. (It's a list of items.) +func (m *Matrix) isSimple() bool { + return len(m.Setup) == 1 && len(m.Setup[""]) != 0 && len(m.Adjustments) == 0 && len(m.RemainingFields) == 0 +} + +// MarshalJSON is needed to use inlineFriendlyMarshalJSON, and reduces the +// representation to a single list if the matrix is simple. +func (m *Matrix) MarshalJSON() ([]byte, error) { + if m.isSimple() { + return json.Marshal(m.Setup[""]) + } + return inlineFriendlyMarshalJSON(m) +} + +// MarshalYAML is needed to reduce the representation to a single slice if +// the matrix is simple. +func (m *Matrix) MarshalYAML() (any, error) { + if m.isSimple() { + return m.Setup[""], nil + } + // Just in case the YAML marshaler tries to call MarshalYAML on the output, + // wrap m in a type without a MarshalYAML method. + type wrappedMatrix Matrix + return (*wrappedMatrix)(m), nil +} + +func (m *Matrix) interpolate(tf stringTransformer) error { + if m == nil { + return nil + } + if _, is := tf.(matrixInterpolator); is { + // Don't interpolate matrixes into matrixes. + return nil + } + if err := interpolateMap(tf, m.Setup); err != nil { + return err + } + if err := interpolateSlice(tf, m.Adjustments); err != nil { + return err + } + return interpolateMap(tf, m.RemainingFields) +} + +// validatePermutation checks that the permutation is a valid selection of +// dimension values, including any non-skipped adjustments. +func (m *Matrix) validatePermutation(p MatrixPermutation) error { + if m == nil { + if len(p) > 0 { + return errNilMatrix + } + // An empty permutation from a nil matrix...seems fine to me? + return nil + } + if len(p) != len(m.Setup) { + return fmt.Errorf("%w: %d != %d", errPermutationLengthMismatch, len(p), len(m.Setup)) + } + + // Check that the dimensions in the permutation are unique and defined in + // the matrix setup. + for dim := range p { + if len(m.Setup[dim]) == 0 { + return fmt.Errorf("%w: %q", errPermutationUnknownDimension, dim) + } + } + + // Check that the permutation values are in the matrix setup (a basic + // permutation). Whether they are or are not, we still check adjustments. + valid := true + for dim, val := range p { + match := false + for _, v := range m.Setup[dim] { + if val == v { + match = true + break + } + } + if !match { + // Not a basic permutation. It could still be an adjustment though. + valid = false + break + } + } + + // Check if the permutation matches any adjustment. + for _, adj := range m.Adjustments { + // Ensure adj.With has the same size and dimension names as m.Setup. + // adj.With is a map so no need to check for repetition. + // Because adjustments can introduce new dimension values, only the + // names of dimensions are checked. + if len(adj.With) != len(m.Setup) { + return fmt.Errorf("%w: %d != %d", errAdjustmentLengthMismatch, len(adj.With), len(m.Setup)) + } + for dim := range adj.With { + if len(m.Setup[dim]) == 0 { + return fmt.Errorf("%w: %q", errAdjustmentUnknownDimension, dim) + } + } + + // Now we can test whether p == adj.With. + match := true + for dim, val := range p { + if val != adj.With[dim] { + match = false + break + } + } + if !match { + continue + } + + if adj.ShouldSkip() { + return errPermutationSkipped + } + // Not skipped, but is an adjustment, so it's valid. + // If multiple adjustments have the same permutation, and any of them + // have "skip: true", then that applies, so we can't bail early. + valid = true + } + + if !valid { + return errPermutationNoMatch + } + return nil +} + +// MatrixPermutation represents a possible permutation of a matrix. +type MatrixPermutation map[string]string + +// MatrixSetup is the main setup of a matrix - one or more dimensions. The cross +// product of the dimensions in the setup produces the base combinations of +// matrix values. +type MatrixSetup map[string][]string + +// MarshalJSON returns either a list (if the setup is a single anonymous +// dimension) or an object (if it contains one or more (named) dimensions). +func (ms MatrixSetup) MarshalJSON() ([]byte, error) { + // Note that MarshalYAML (below) always returns nil error. + o, _ := ms.MarshalYAML() + return json.Marshal(o) +} + +// MarshalYAML returns either a Scalars (if the setup is a single anonymous +// dimension) or a map (if it contains one or more (named) dimensions). +func (ms MatrixSetup) MarshalYAML() (any, error) { + if len(ms) == 1 && len(ms[""]) > 0 { + return ms[""], nil + } + return map[string][]string(ms), nil +} + +// UnmarshalOrdered unmarshals from either []any or *ordered.MapSA. +func (ms *MatrixSetup) UnmarshalOrdered(o any) error { + if *ms == nil { + *ms = make(MatrixSetup) + } + switch src := o.(type) { + case []any: + // Single anonymous dimension, but we only get here if its under a setup + // key. (Maybe the user wants adjustments for their single dimension.) + // + // matrix: + // setup: + // - apple + // - 47 + s := make([]string, 0, len(src)) + if err := ordered.Unmarshal(src, &s); err != nil { + return err + } + (*ms)[""] = s + + case *ordered.MapSA: + // One or more (named) dimensions. + // Unmarshal into the underlying type to avoid infinite recursion. + if err := ordered.Unmarshal(src, (*map[string][]string)(ms)); err != nil { + return err + } + + default: + return fmt.Errorf("unsupported src type for MatrixSetup: %T", o) + } + return nil +} + +// MatrixAdjustments is a set of adjustments. +type MatrixAdjustments []*MatrixAdjustment + +// MatrixAdjustment models an adjustment - a combination of (possibly new) +// matrix values, and skip/soft fail configuration. +type MatrixAdjustment struct { + With MatrixAdjustmentWith `yaml:"with"` + Skip any `yaml:"skip,omitempty"` + + RemainingFields map[string]any `yaml:",inline"` // NB: soft_fail is in the remaining fields +} + +func (ma *MatrixAdjustment) ShouldSkip() bool { + switch s := ma.Skip.(type) { + case bool: + return s + + case nil: + return false + + default: + return true + } +} + +// MarshalJSON is needed to use inlineFriendlyMarshalJSON. +func (ma *MatrixAdjustment) MarshalJSON() ([]byte, error) { + return inlineFriendlyMarshalJSON(ma) +} + +func (ma *MatrixAdjustment) interpolate(tf stringTransformer) error { + if ma == nil { + return nil + } + if err := interpolateMap(tf, ma.With); err != nil { + return err + } + return interpolateMap(tf, ma.RemainingFields) +} + +// MatrixAdjustmentWith is either a map of dimension key -> dimension value, +// or a single value (for single anonymous dimension matrices). +type MatrixAdjustmentWith map[string]string + +// MarshalJSON returns either a single scalar or an object. +func (maw MatrixAdjustmentWith) MarshalJSON() ([]byte, error) { + // Note that MarshalYAML (below) always returns nil error. + o, _ := maw.MarshalYAML() + return json.Marshal(o) +} + +// MarshalYAML returns either a single scalar or a map. +func (maw MatrixAdjustmentWith) MarshalYAML() (any, error) { + if _, has := maw[""]; has && len(maw) == 1 { + return maw[""], nil + } + return map[string]string(maw), nil +} + +// UnmarshalOrdered unmarshals from either a scalar value (string, bool, or int) +// or *ordered.MapSA. +func (maw *MatrixAdjustmentWith) UnmarshalOrdered(o any) error { + if *maw == nil { + *maw = make(MatrixAdjustmentWith) + } + + switch src := o.(type) { + case bool, int, string: + // A single scalar. + // (This is how you can do adjustments on a single anonymous dimension.) + // + // matrix: + // setup: + // - apple + // - 47 + // adjustments: + // - with: banana + // soft_fail: true + (*maw)[""] = fmt.Sprint(src) + + case *ordered.MapSA: + // A map of dimension key -> dimension value. (Tuple of dimension value + // selections.) + return src.Range(func(k string, v any) error { + switch vt := v.(type) { + case bool, int, string: + (*maw)[k] = fmt.Sprint(vt) + + default: + return fmt.Errorf("unsupported value type %T in key %q for MatrixAdjustmentsWith", v, k) + } + return nil + }) + + default: + return fmt.Errorf("unsupported src type for MatrixAdjustmentsWith: %T", o) + } + return nil +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_group.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_group.go new file mode 100644 index 000000000..ee136c0a4 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_group.go @@ -0,0 +1,57 @@ +package pipeline + +import ( + "fmt" + + "github.com/buildkite/agent/v3/internal/ordered" +) + +// GroupStep models a group step. +// +// Standard caveats apply - see the package comment. +type GroupStep struct { + // Group is typically a key with no value. Since it must always exist in + // a group step, here it is. + Group *string `yaml:"group"` + + Steps Steps `yaml:"steps"` + + // RemainingFields stores any other top-level mapping items so they at least + // survive an unmarshal-marshal round-trip. + RemainingFields map[string]any `yaml:",inline"` +} + +// UnmarshalOrdered unmarshals a group step from an ordered map. +func (g *GroupStep) UnmarshalOrdered(src any) error { + type wrappedGroup GroupStep + if err := ordered.Unmarshal(src, (*wrappedGroup)(g)); err != nil { + return fmt.Errorf("unmarshalling GroupStep: %w", err) + } + + // Ensure Steps is never nil. Server side expects a sequence. + if g.Steps == nil { + g.Steps = Steps{} + } + return nil +} + +func (g *GroupStep) interpolate(tf stringTransformer) error { + grp, err := interpolateAny(tf, g.Group) + if err != nil { + return err + } + g.Group = grp + + if err := g.Steps.interpolate(tf); err != nil { + return err + } + return interpolateMap(tf, g.RemainingFields) +} + +func (GroupStep) stepTag() {} + +// MarshalJSON marshals the step to JSON. Special handling is needed because +// yaml.v3 has "inline" but encoding/json has no concept of it. +func (g *GroupStep) MarshalJSON() ([]byte, error) { + return inlineFriendlyMarshalJSON(g) +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_input.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_input.go new file mode 100644 index 000000000..cfe769be1 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_input.go @@ -0,0 +1,34 @@ +package pipeline + +import ( + "encoding/json" + "errors" +) + +// See the comment in step_scalar.go. + +// InputStep models a block or input step. +// +// Standard caveats apply - see the package comment. +type InputStep struct { + Scalar string `yaml:"-"` + Contents map[string]any `yaml:",inline"` +} + +func (s *InputStep) MarshalJSON() ([]byte, error) { + if s.Scalar != "" { + return json.Marshal(s.Scalar) + } + + if len(s.Contents) == 0 { + return []byte{}, errors.New("empty input step") + } + + return json.Marshal(s.Contents) +} + +func (s InputStep) interpolate(tf stringTransformer) error { + return interpolateMap(tf, s.Contents) +} + +func (*InputStep) stepTag() {} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_scalar.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_scalar.go new file mode 100644 index 000000000..721ac0254 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_scalar.go @@ -0,0 +1,41 @@ +package pipeline + +import "fmt" + +// In the buildkite pipeline yaml, some step types (broadly, wait steps, input steps and block steps) can be represented +// either by a scalar string (ie "wait") or by a mapping with keys and values and such +// +// This behaviour is difficult to cleanly model in go, which leads to the somewhat odd structure of the structs defined +// in this file - each type (WaitStep, InputStep) has a Scalar field which is set to the scalar value if the step was +// if, during pipeline parsing, the step was represented as a scalar, and is left empty if the step was represented as +// a mapping. In essence, if one of the fields of these structs is filled, the other should be empty. +// +// On the unmarshalling side, the differing types is handled by the steps parser - see the unmarshalStep() function in +// ./steps.go - it infers the underlying type of the thing it's unmarshalling, and if it's a string, calls NewScalarStep() +// (below) to create the appropriate struct. If it's a mapping, it creates the appropriate struct directly. +// +// On the marshalling side, the MarshalJSON() function on each struct handles the different cases. In general, if the +// Scalar field is set, it marshals that, otherwise it marshals the other fields. +// +// In reading this file, you may have noticed that I mentioned that there are three types of step that can be represented +// as a scalar, but there are only two structs defined here. This is because the third type, block steps, are represented +// in exactly the same way as input steps, so they can share the same struct. This is liable to change in the future, +// as conceptually they're different types, and it makes sense to have them as different types in go as well. +// +// Also also! The implementations for WaitStep and InputStep **almost**, but not quite identical. This is due to the behaviour +// of marshalling an empty struct into into JSON. For WaitStep, it makes sense that the empty &WaitStep{} struct marshals +// to "wait", but with InputStep, there's no way to tell whether it should be marshalled to "input" or "block", which +// have very different behaviour on the backend. + +var validStepScalars = []string{"wait", "waiter", "block", "input", "manual"} + +func NewScalarStep(s string) (Step, error) { + switch s { + case "wait", "waiter": + return &WaitStep{Scalar: s}, nil + case "block", "input", "manual": + return &InputStep{Scalar: s}, nil + default: + return nil, fmt.Errorf("unmarshaling step: unsupported scalar step type %q, want one of %v", s, validStepScalars) + } +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_trigger.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_trigger.go new file mode 100644 index 000000000..7513b4171 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_trigger.go @@ -0,0 +1,23 @@ +package pipeline + +import ( + "encoding/json" +) + +// TriggerStep models a trigger step. +// +// Standard caveats apply - see the package comment. +type TriggerStep struct { + Contents map[string]any `yaml:",inline"` +} + +// MarshalJSON marshals the contents of the step. +func (t TriggerStep) MarshalJSON() ([]byte, error) { + return json.Marshal(t.Contents) +} + +func (s TriggerStep) interpolate(tf stringTransformer) error { + return interpolateMap(tf, s.Contents) +} + +func (TriggerStep) stepTag() {} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_unknown.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_unknown.go new file mode 100644 index 000000000..0b0161515 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_unknown.go @@ -0,0 +1,40 @@ +package pipeline + +import ( + "encoding/json" +) + +// UnknownStep models any step we don't know how to represent in this version. +// When future step types are added, they should be parsed with more specific +// types. UnknownStep is present to allow older parsers to preserve newer +// pipelines. +type UnknownStep struct { + Contents any +} + +// MarshalJSON marshals the contents of the step. +func (u UnknownStep) MarshalJSON() ([]byte, error) { + return json.Marshal(u.Contents) +} + +// MarshalYAML returns the contents of the step. +func (u UnknownStep) MarshalYAML() (any, error) { + return u.Contents, nil +} + +// UnmarshalOrdered unmarshals an unknown step. +func (u *UnknownStep) UnmarshalOrdered(src any) error { + u.Contents = src + return nil +} + +func (u *UnknownStep) interpolate(tf stringTransformer) error { + c, err := interpolateAny(tf, u.Contents) + if err != nil { + return err + } + u.Contents = c + return nil +} + +func (UnknownStep) stepTag() {} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_wait.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_wait.go new file mode 100644 index 000000000..5c7ad2321 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/step_wait.go @@ -0,0 +1,35 @@ +package pipeline + +import ( + "encoding/json" +) + +// See the comment in step_scalar.go. + +// WaitStep models a wait step. +// +// Standard caveats apply - see the package comment. +type WaitStep struct { + Scalar string `yaml:"-"` + Contents map[string]any `yaml:",inline"` +} + +// MarshalJSON marshals a wait step as "wait" if w is empty, or as the step's scalar if it's set. +// If scalar is empty, it marshals as the remaining fields +func (s *WaitStep) MarshalJSON() ([]byte, error) { + if s.Scalar != "" { + return json.Marshal(s.Scalar) + } + + if len(s.Contents) == 0 { + return json.Marshal("wait") + } + + return json.Marshal(s.Contents) +} + +func (s *WaitStep) interpolate(tf stringTransformer) error { + return interpolateMap(tf, s.Contents) +} + +func (*WaitStep) stepTag() {} diff --git a/vendor/github.com/buildkite/agent/v3/internal/pipeline/steps.go b/vendor/github.com/buildkite/agent/v3/internal/pipeline/steps.go new file mode 100644 index 000000000..f0b896ed6 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/internal/pipeline/steps.go @@ -0,0 +1,170 @@ +package pipeline + +import ( + "errors" + "fmt" + + "github.com/buildkite/agent/v3/internal/ordered" + "github.com/lestrrat-go/jwx/v2/jwk" +) + +var errSigningRefusedUnknownStepType = errors.New("refusing to sign pipeline containing a step of unknown type, because the pipeline could be incorrectly parsed - please contact support") + +// Steps contains multiple steps. It is useful for unmarshaling step sequences, +// since it has custom logic for determining the correct step type. +type Steps []Step + +// UnmarshalOrdered unmarshals a slice ([]any) into a slice of steps. +func (s *Steps) UnmarshalOrdered(o any) error { + if o == nil { + if *s == nil { + // `steps: null` is normalised to an empty slice. + *s = Steps{} + } + return nil + } + sl, ok := o.([]any) + if !ok { + return fmt.Errorf("unmarshaling steps: got %T, want a slice ([]any)", sl) + } + // Preallocate slice if not already allocated + if *s == nil { + *s = make(Steps, 0, len(sl)) + } + for _, st := range sl { + step, err := unmarshalStep(st) + if err != nil { + return err + } + *s = append(*s, step) + } + return nil +} + +func (s Steps) interpolate(tf stringTransformer) error { + return interpolateSlice(tf, s) +} + +// unmarshalStep unmarshals into the right kind of Step. +func unmarshalStep(o any) (Step, error) { + switch o := o.(type) { + case string: + step, err := NewScalarStep(o) + if err != nil { + return &UnknownStep{Contents: o}, nil + } + return step, nil + + case *ordered.MapSA: + return stepFromMap(o) + + default: + return nil, fmt.Errorf("unmarshaling step: unsupported type %T", o) + } +} + +func stepFromMap(o *ordered.MapSA) (Step, error) { + sType, hasType := o.Get("type") + + var step Step + var err error + if hasType { + sTypeStr, ok := sType.(string) + if !ok { + return nil, fmt.Errorf("unmarshaling step: step's `type` key was %T (value %v), want string", sType, sType) + } + + step, err = stepByType(sTypeStr) + if err != nil { + return nil, fmt.Errorf("unmarshaling step: %w", err) + } + } else { + step, err = stepByKeyInference(o) + if err != nil { + return nil, fmt.Errorf("unmarshaling step: %w", err) + } + } + + // Decode the step (into the right step type). + if err := ordered.Unmarshal(o, step); err != nil { + // Hmm, maybe we picked the wrong kind of step? + return &UnknownStep{Contents: o}, nil + } + return step, nil +} + +func stepByType(sType string) (Step, error) { + switch sType { + case "command", "script": + return new(CommandStep), nil + case "wait", "waiter": + return &WaitStep{Contents: map[string]any{}}, nil + case "block", "input", "manual": + return &InputStep{Contents: map[string]any{}}, nil + case "trigger": + return new(TriggerStep), nil + case "group": // as far as i know this doesn't happen, but it's here for completeness + return new(GroupStep), nil + default: + return nil, fmt.Errorf("unknown step type %q", sType) + } +} + +func stepByKeyInference(o *ordered.MapSA) (Step, error) { + switch { + case o.Contains("command") || o.Contains("commands") || o.Contains("plugins"): + // NB: Some "command" step are commandless containers that exist + // just to run plugins! + return new(CommandStep), nil + + case o.Contains("wait") || o.Contains("waiter"): + return new(WaitStep), nil + + case o.Contains("block") || o.Contains("input") || o.Contains("manual"): + return new(InputStep), nil + + case o.Contains("trigger"): + return new(TriggerStep), nil + + case o.Contains("group"): + return new(GroupStep), nil + + default: + return new(UnknownStep), nil + } +} + +// sign adds signatures to each command step (and recursively to any command +// steps that are within group steps. The steps are mutated directly, so an +// error part-way through may leave some steps un-signed. +func (s Steps) sign(key jwk.Key, env map[string]string, pInv *PipelineInvariants) error { + for _, step := range s { + switch step := step.(type) { + case *CommandStep: + stepWithInvariants := &CommandStepWithPipelineInvariants{ + CommandStep: *step, + PipelineInvariants: *pInv, + } + + sig, err := Sign(key, env, stepWithInvariants) + if err != nil { + return fmt.Errorf("signing step with command %q: %w", step.Command, err) + } + step.Signature = sig + + case *GroupStep: + if err := step.Steps.sign(key, env, pInv); err != nil { + return fmt.Errorf("signing group step: %w", err) + } + + case *UnknownStep: + // Presence of an unknown step means we're missing some semantic + // information about the pipeline. We could be not signing something + // that needs signing. Rather than deferring the problem (so that + // signature verification fails when an agent runs jobs) we return + // an error now. + return errSigningRefusedUnknownStepType + } + } + return nil +} diff --git a/vendor/github.com/buildkite/agent/v3/logger/buffer.go b/vendor/github.com/buildkite/agent/v3/logger/buffer.go index 9aa3b4f8f..84480b751 100644 --- a/vendor/github.com/buildkite/agent/v3/logger/buffer.go +++ b/vendor/github.com/buildkite/agent/v3/logger/buffer.go @@ -2,11 +2,13 @@ package logger import ( "fmt" + "sync" ) // Buffer is a Logger implementation intended for testing; // messages are stored internally. type Buffer struct { + mu sync.Mutex Messages []string } @@ -20,21 +22,33 @@ func NewBuffer() *Buffer { } func (b *Buffer) Debug(format string, v ...any) { + b.mu.Lock() + defer b.mu.Unlock() b.Messages = append(b.Messages, "[debug] "+fmt.Sprintf(format, v...)) } func (b *Buffer) Error(format string, v ...any) { + b.mu.Lock() + defer b.mu.Unlock() b.Messages = append(b.Messages, "[error] "+fmt.Sprintf(format, v...)) } func (b *Buffer) Fatal(format string, v ...any) { + b.mu.Lock() + defer b.mu.Unlock() b.Messages = append(b.Messages, "[fatal] "+fmt.Sprintf(format, v...)) } func (b *Buffer) Notice(format string, v ...any) { + b.mu.Lock() + defer b.mu.Unlock() b.Messages = append(b.Messages, "[notice] "+fmt.Sprintf(format, v...)) } func (b *Buffer) Warn(format string, v ...any) { + b.mu.Lock() + defer b.mu.Unlock() b.Messages = append(b.Messages, "[warn] "+fmt.Sprintf(format, v...)) } func (b *Buffer) Info(format string, v ...any) { + b.mu.Lock() + defer b.mu.Unlock() b.Messages = append(b.Messages, "[info] "+fmt.Sprintf(format, v...)) } func (b *Buffer) WithFields(fields ...Field) Logger { diff --git a/vendor/github.com/buildkite/agent/v3/logger/log.go b/vendor/github.com/buildkite/agent/v3/logger/log.go index 0147ad232..6807b5b8a 100644 --- a/vendor/github.com/buildkite/agent/v3/logger/log.go +++ b/vendor/github.com/buildkite/agent/v3/logger/log.go @@ -14,6 +14,7 @@ import ( "sync" "time" + "github.com/buildkite/agent/v3/version" "golang.org/x/crypto/ssh/terminal" ) @@ -80,7 +81,10 @@ func (l *ConsoleLogger) SetLevel(level Level) { func (l *ConsoleLogger) Debug(format string, v ...any) { if l.level == DEBUG { - l.printer.Print(DEBUG, fmt.Sprintf(format, v...), l.fields) + debugFields := make(Fields, len(l.fields)) + copy(debugFields, l.fields) + debugFields.Add(StringField("agent_version", version.FullVersion())) + l.printer.Print(DEBUG, fmt.Sprintf(format, v...), debugFields) } } diff --git a/vendor/github.com/buildkite/agent/v3/tracetools/doc.go b/vendor/github.com/buildkite/agent/v3/tracetools/doc.go new file mode 100644 index 000000000..6900422e3 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/tracetools/doc.go @@ -0,0 +1,5 @@ +// Package tracetools provides an abstraction across tracing systems +// (OpenTelemetry, DataDog). +// +// It is intended for internal use by buildkite-agent only. +package tracetools diff --git a/vendor/github.com/buildkite/agent/v3/tracetools/propagate.go b/vendor/github.com/buildkite/agent/v3/tracetools/propagate.go new file mode 100644 index 000000000..1f8bc27d9 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/tracetools/propagate.go @@ -0,0 +1,55 @@ +package tracetools + +import ( + "bytes" + "encoding/base64" + "encoding/gob" + + "github.com/opentracing/opentracing-go" + "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" +) + +// EnvVarTraceContextKey is the env var key that will be used to store/retrieve the +// encoded trace context information into env var maps. +const EnvVarTraceContextKey = "BUILDKITE_TRACE_CONTEXT" + +// EncodeTraceContext will serialize and encode tracing data into a string and place +// it into the given env vars map. +func EncodeTraceContext(span opentracing.Span, env map[string]string) error { + textmap := tracer.TextMapCarrier{} + if err := span.Tracer().Inject(span.Context(), opentracing.TextMap, &textmap); err != nil { + return err + } + + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(textmap); err != nil { + return err + } + + env[EnvVarTraceContextKey] = base64.URLEncoding.EncodeToString(buf.Bytes()) + return nil +} + +// DecodeTraceContext will decode, deserialize, and extract the tracing data from the +// given env var map. +func DecodeTraceContext(env map[string]string) (opentracing.SpanContext, error) { + s, has := env[EnvVarTraceContextKey] + if !has { + return nil, opentracing.ErrSpanContextNotFound + } + + contextBytes, err := base64.URLEncoding.DecodeString(s) + if err != nil { + return nil, err + } + + buf := bytes.NewBuffer(contextBytes) + dec := gob.NewDecoder(buf) + textmap := opentracing.TextMapCarrier{} + if err := dec.Decode(&textmap); err != nil { + return nil, err + } + + return opentracing.GlobalTracer().Extract(opentracing.TextMap, textmap) +} diff --git a/vendor/github.com/buildkite/agent/v3/tracetools/span.go b/vendor/github.com/buildkite/agent/v3/tracetools/span.go new file mode 100644 index 000000000..f966a5595 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/tracetools/span.go @@ -0,0 +1,129 @@ +package tracetools + +import ( + "context" + + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/trace" + ddext "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext" +) + +const ( + BackendDatadog = "datadog" + BackendOpenTelemetry = "opentelemetry" + BackendNone = "" +) + +var ValidTracingBackends = map[string]struct{}{ + BackendDatadog: {}, + BackendOpenTelemetry: {}, + BackendNone: {}, +} + +// StartSpanFromContext will start a span appropriate to the given tracing backend from the given context with the given +// operation name. It will also do some common/repeated setup on the span to keep code a little more DRY. +// If an unknown tracing backend is specified, it will return a span that noops on every operation +func StartSpanFromContext(ctx context.Context, operation string, tracingBackend string) (Span, context.Context) { + switch tracingBackend { + case BackendDatadog: + span, ctx := opentracing.StartSpanFromContext(ctx, operation) + span.SetTag(ddext.AnalyticsEvent, true) // Make the span available for analytics in Datadog + return NewOpenTracingSpan(span), ctx + + case BackendOpenTelemetry: + ctx, span := otel.Tracer("buildkite-agent").Start(ctx, operation) + span.SetAttributes(attribute.String("analytics.event", "true")) + return &OpenTelemetrySpan{Span: span}, ctx + + case BackendNone: + fallthrough + + default: + return &NoopSpan{}, ctx + } +} + +type Span interface { + AddAttributes(map[string]string) + FinishWithError(error) + RecordError(error) +} + +type OpenTracingSpan struct { + Span opentracing.Span +} + +func NewOpenTracingSpan(base opentracing.Span) *OpenTracingSpan { + return &OpenTracingSpan{Span: base} +} + +// AddAttributes adds the given map of attributes to the span as OpenTracing tags +func (s *OpenTracingSpan) AddAttributes(attributes map[string]string) { + for k, v := range attributes { + s.Span.SetTag(k, v) + } +} + +// FinishWithError adds error information to the OpenTracingSpan if error isn't nil, and records the span as having finished +func (s *OpenTracingSpan) FinishWithError(err error) { + s.RecordError(err) + s.Span.Finish() +} + +// RecordError records an error on the given span +func (s *OpenTracingSpan) RecordError(err error) { + if err == nil { + return + } + + ext.LogError(s.Span, err) +} + +type OpenTelemetrySpan struct { + Span trace.Span +} + +func NewOpenTelemetrySpan(base trace.Span) *OpenTelemetrySpan { + return &OpenTelemetrySpan{Span: base} +} + +// AddAttributes adds the given attributes to the OpenTelemetry span. Only string attributes are accepted. +func (s *OpenTelemetrySpan) AddAttributes(attributes map[string]string) { + for k, v := range attributes { + s.Span.SetAttributes(attribute.String(k, v)) + } +} + +// FinishWithError adds error information to the OpenTelemetry span if error isn't nil, and records the span as having finished +func (s *OpenTelemetrySpan) FinishWithError(err error) { + s.RecordError(err) + s.Span.End() +} + +// RecordError records an error on the given OpenTelemetry span. No-op when error is nil +func (s *OpenTelemetrySpan) RecordError(err error) { + if err == nil { + return + } + + s.Span.RecordError(err) + s.Span.SetStatus(codes.Error, "failed") +} + +// NoopSpan is an implementation of the Span interface that does nothing for every method implemented +// The intended use case is for instances where the user doesn't have tracing enabled - using NoopSpan, we can still act +// as though tracing is enabled, but every time we do something tracing related, nothing happens. +type NoopSpan struct{} + +// AddAttributes is a noop +func (s *NoopSpan) AddAttributes(attributes map[string]string) {} + +// FinishWithError is a noop +func (s *NoopSpan) FinishWithError(err error) {} + +// RecordError is a noop +func (s *NoopSpan) RecordError(err error) {} diff --git a/vendor/github.com/buildkite/agent/v3/version/VERSION b/vendor/github.com/buildkite/agent/v3/version/VERSION new file mode 100644 index 000000000..69ef73e1d --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/version/VERSION @@ -0,0 +1 @@ +3.58.0 diff --git a/vendor/github.com/buildkite/agent/v3/version/version.go b/vendor/github.com/buildkite/agent/v3/version/version.go new file mode 100644 index 000000000..09eefeda0 --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/version/version.go @@ -0,0 +1,81 @@ +// Package version provides the agent version strings. +package version + +import ( + _ "embed" + "fmt" + "runtime" + "runtime/debug" + "strings" +) + +// Pre-release builds' versions must be in the format `x.y-beta`, `x.y-beta.z` or `x.y-beta.z.a` + +var ( + //go:embed VERSION + baseVersion string + buildNumber = "x" +) + +func Version() string { + return strings.TrimSpace(baseVersion) +} + +// BuildNumber returns the build number of the CI pipeline that built the agent. +// You can override buildVersion at compile time by using the ldflag: +// +// "-X github.com/buildkite/agent/v3/version.buildNumber=abc" +// +// An easy way to test this is: +// +// $ go run -buildvcs=true -ldflags "-X github.com/buildkite/agent/v3/version.buildNumber=abc" . --version +// +// On CI, the binaries are always built with the buildVersion variable set. +func BuildNumber() string { + return buildNumber +} + +// commitInfo returns a string consisting of the commit hash and whether the the build was made in a +// `dirty` working directory or not. A dirty working directory is one that has uncommitted changes +// to files that git would track. +func commitInfo() string { + info, ok := debug.ReadBuildInfo() + if !ok { + return "x" + } + + dirty := ".dirty" + var commit string + for _, setting := range info.Settings { + switch setting.Key { + case "vcs.revision": + commit = setting.Value + case "vcs.modified": + if setting.Value == "false" { + dirty = "" + } + } + } + + return commit + dirty +} + +// FullVersion is a SemVer 2.0 compliant version string that includes +// [build metadata](https://semver.org/#spec-item-10) consisting of the build +// number (if any), the commit hash, and whether the build was made in a `dirty` +// working directory or not. +func FullVersion() string { + return fmt.Sprintf("%s+%s.%s", Version(), BuildNumber(), commitInfo()) +} + +// UserAgent returns a string suitable for use as a User-Agent header. +// TODO-vNext: Include some prefix of the commit hash in the User-Agent header. +func UserAgent() string { + return fmt.Sprintf( + "buildkite-agent/%s.%s (%s; %s)", + Version(), + BuildNumber(), + runtime.GOOS, + runtime.GOARCH, + ) +} diff --git a/vendor/github.com/buildkite/interpolate/LICENSE.txt b/vendor/github.com/buildkite/interpolate/LICENSE.txt new file mode 100644 index 000000000..951b6ced4 --- /dev/null +++ b/vendor/github.com/buildkite/interpolate/LICENSE.txt @@ -0,0 +1,24 @@ +# Buildkite Licence + +Copyright (c) 2014-2017 Buildkite Pty Ltd + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/buildkite/interpolate/README.md b/vendor/github.com/buildkite/interpolate/README.md new file mode 100644 index 000000000..ec2790efd --- /dev/null +++ b/vendor/github.com/buildkite/interpolate/README.md @@ -0,0 +1,61 @@ +Interpolate +=========== + +[![GoDoc](https://godoc.org/github.com/buildkite/interpolate?status.svg)](https://godoc.org/github.com/buildkite/interpolate) + +A golang library for parameter expansion (like `${BLAH}` or `$BLAH`) in strings from environment variables. An implementation of [POSIX Parameter Expansion](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02), plus some other basic operations that you'd expect in a shell scripting environment [like bash](https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html). + +## Installation + +``` +go get -u github.com/buildkite/interpolate +``` + +## Usage + +```go +package main + +import ( + "github.com/buildkite/interpolate" + "fmt" +) + +func main() { + env := interpolate.NewSliceEnv([]string{ + "HELLO_WORLD=🦀", + }) + + output, _ := interpolate.Interpolate(env, "Buildkite... ${HELLO_WORLD} ${ANOTHER_VAR:-🏖}") + fmt.Println(output) +} + +// Output: Buildkite... 🦀 🏖 + +``` + +## Supported Expansions + +

+
${parameter} or $parameter
+
Use value. If parameter is set, then it shall be substituted; otherwise it will be blank
+ +
${parameter:-[word]}
+
Use default values. If parameter is unset or null, the expansion of word (or an empty string if word is omitted) shall be substituted; otherwise, the value of parameter shall be substituted.
+ +
${parameter-[word]}
+
Use default values when not set. If parameter is unset, the expansion of word (or an empty string if word is omitted) shall be substituted; otherwise, the value of parameter shall be substituted.
+ +
${parameter:[offset]}
+
Use the substring of parameter after offset. A negative offset must be separated from the colon with a space, and will select from the end of the string. If the value is out of bounds, an empty string will be substituted.
+ +
${parameter:[offset]:[length]}
+
Use the substring of parameter after offset of given length. A negative offset must be separated from the colon with a space, and will select from the end of the string. If the offset is out of bounds, an empty string will be substituted. If the length is greater than the length then the entire string will be returned.
+ +
${parameter:?[word]}
+
Indicate Error if Null or Unset. If parameter is unset or null, the expansion of word (or a message indicating it is unset if word is omitted) shall be returned as an error.
+
+ +## License + +Licensed under MIT license, in `LICENSE`. diff --git a/vendor/github.com/buildkite/interpolate/env.go b/vendor/github.com/buildkite/interpolate/env.go new file mode 100644 index 000000000..8966a264f --- /dev/null +++ b/vendor/github.com/buildkite/interpolate/env.go @@ -0,0 +1,49 @@ +package interpolate + +import ( + "runtime" + "strings" +) + +type Env interface { + Get(key string) (string, bool) +} + +// Creates an Env from a slice of environment variables +func NewSliceEnv(env []string) Env { + envMap := mapEnv{} + for _, l := range env { + parts := strings.SplitN(l, "=", 2) + if len(parts) == 2 { + envMap[normalizeKeyName(parts[0])] = parts[1] + } + } + return envMap +} + +// Creates an Env from a map of environment variables +func NewMapEnv(env map[string]string) Env { + envMap := mapEnv{} + for k, v := range env { + envMap[normalizeKeyName(k)] = v + } + return envMap +} + +type mapEnv map[string]string + +func (m mapEnv) Get(key string) (string, bool) { + if m == nil { + return "", false + } + val, ok := m[normalizeKeyName(key)] + return val, ok +} + +// Windows isn't case sensitive for env +func normalizeKeyName(key string) string { + if runtime.GOOS == "windows" { + return strings.ToUpper(key) + } + return key +} diff --git a/vendor/github.com/buildkite/interpolate/interpolate.go b/vendor/github.com/buildkite/interpolate/interpolate.go new file mode 100644 index 000000000..90d5ee3cc --- /dev/null +++ b/vendor/github.com/buildkite/interpolate/interpolate.go @@ -0,0 +1,212 @@ +package interpolate + +import ( + "bytes" + "fmt" +) + +// Interpolate takes a set of environment and interpolates it into the provided string using shell script expansions +func Interpolate(env Env, str string) (string, error) { + if env == nil { + env = NewSliceEnv(nil) + } + expr, err := NewParser(str).Parse() + if err != nil { + return "", err + } + return expr.Expand(env) +} + +// Indentifiers parses the identifiers from any expansions in the provided string +func Identifiers(str string) ([]string, error) { + expr, err := NewParser(str).Parse() + if err != nil { + return nil, err + } + return expr.Identifiers(), nil +} + +// An expansion is something that takes in ENV and returns a string or an error +type Expansion interface { + Expand(env Env) (string, error) + Identifiers() []string +} + +// VariableExpansion represents either $VAR or ${VAR}, our simplest expansion +type VariableExpansion struct { + Identifier string +} + +func (e VariableExpansion) Identifiers() []string { + return []string{e.Identifier} +} + +func (e VariableExpansion) Expand(env Env) (string, error) { + val, _ := env.Get(e.Identifier) + return val, nil +} + +// EmptyValueExpansion returns either the value of an env, or a default value if it's unset or null +type EmptyValueExpansion struct { + Identifier string + Content Expression +} + +func (e EmptyValueExpansion) Identifiers() []string { + return append([]string{e.Identifier}, e.Content.Identifiers()...) +} + +func (e EmptyValueExpansion) Expand(env Env) (string, error) { + val, _ := env.Get(e.Identifier) + if val == "" { + return e.Content.Expand(env) + } + return val, nil +} + +// UnsetValueExpansion returns either the value of an env, or a default value if it's unset +type UnsetValueExpansion struct { + Identifier string + Content Expression +} + +func (e UnsetValueExpansion) Identifiers() []string { + return []string{e.Identifier} +} + +func (e UnsetValueExpansion) Expand(env Env) (string, error) { + val, ok := env.Get(e.Identifier) + if !ok { + return e.Content.Expand(env) + } + return val, nil +} + +// SubstringExpansion returns a substring (or slice) of the env +type SubstringExpansion struct { + Identifier string + Offset int + Length int + HasLength bool +} + +func (e SubstringExpansion) Identifiers() []string { + return []string{e.Identifier} +} + +func (e SubstringExpansion) Expand(env Env) (string, error) { + val, _ := env.Get(e.Identifier) + + from := e.Offset + + // Negative offsets = from end + if from < 0 { + from += len(val) + } + + // Still negative = too far from end? Truncate to start. + if from < 0 { + from = 0 + } + + // Beyond end? Truncate to end. + if from > len(val) { + from = len(val) + } + + if !e.HasLength { + return val[from:], nil + } + + to := e.Length + + if to >= 0 { + // Positive length = from offset + to += from + } else { + // Negative length = from end + to += len(val) + + // Too far? Truncate to offset. + if to < from { + to = from + } + } + + // Beyond end? Truncate to end. + if to > len(val) { + to = len(val) + } + + return val[from:to], nil +} + +// RequiredExpansion returns an env value, or an error if it is unset +type RequiredExpansion struct { + Identifier string + Message Expression +} + +func (e RequiredExpansion) Identifiers() []string { + return []string{e.Identifier} +} + +func (e RequiredExpansion) Expand(env Env) (string, error) { + val, ok := env.Get(e.Identifier) + if !ok { + msg, err := e.Message.Expand(env) + if err != nil { + return "", err + } + if msg == "" { + msg = "not set" + } + return "", fmt.Errorf("$%s: %s", e.Identifier, msg) + } + return val, nil +} + +// Expression is a collection of either Text or Expansions +type Expression []ExpressionItem + +func (e Expression) Identifiers() []string { + identifiers := []string{} + for _, item := range e { + if item.Expansion != nil { + identifiers = append(identifiers, item.Expansion.Identifiers()...) + } + } + return identifiers +} + +func (e Expression) Expand(env Env) (string, error) { + buf := &bytes.Buffer{} + + for _, item := range e { + if item.Expansion != nil { + result, err := item.Expansion.Expand(env) + if err != nil { + return "", err + } + _, _ = buf.WriteString(result) + } else { + _, _ = buf.WriteString(item.Text) + } + } + + return buf.String(), nil +} + +// ExpressionItem models either an Expansion or Text. Either/Or, never both. +type ExpressionItem struct { + Text string + // -- or -- + Expansion Expansion +} + +func (i ExpressionItem) String() string { + if i.Expansion != nil { + return fmt.Sprintf("%#v", i.Expansion) + } + return fmt.Sprintf("%q", i.Text) +} diff --git a/vendor/github.com/buildkite/interpolate/parser.go b/vendor/github.com/buildkite/interpolate/parser.go new file mode 100644 index 000000000..fa7e84340 --- /dev/null +++ b/vendor/github.com/buildkite/interpolate/parser.go @@ -0,0 +1,287 @@ +package interpolate + +import ( + "fmt" + "strconv" + "strings" + "unicode" + "unicode/utf8" +) + +// This is a recursive descent parser for our grammar. Because it can contain nested expressions like +// ${LLAMAS:-${ROCK:-true}} we can't use regular expressions. The simplest possible alternative is +// a recursive parser like this. It parses a chunk and then calls a function to parse that further +// and so on and so forth. It results in a tree of objects that represent the things we've parsed (an AST). +// This means that the logic for how expansions work lives in those objects, and the logic for how we go +// from plain text to parsed objects lives here. +// +// To keep things simple, we do our "lexing" or "scanning" just as a few functions at the end of the file +// rather than as a dedicated lexer that emits tokens. This matches the simplicity of the format we are parsing +// relatively well +// +// Below is an EBNF grammar for the language. The parser was built by basically turning this into functions +// and structs named the same reading the string bite by bite (peekRune and nextRune) + +/* +EscapedBackslash = "\\" +EscapedDollar = ( "\$" | "$$") +Identifier = letter { letters | digit | "_" } +Expansion = "$" ( Identifier | Brace ) +Brace = "{" Identifier [ Identifier BraceOperation ] "}" +Text = { EscapedBackslash | EscapedDollar | all characters except "$" } +Expression = { Text | Expansion } +EmptyValue = ":-" { Expression } +UnsetValue = "-" { Expression } +Substring = ":" number [ ":" number ] +Required = "?" { Expression } +Operation = EmptyValue | UnsetValue | Substring | Required +*/ + +const ( + eof = -1 +) + +// Parser takes a string and parses out a tree of structs that represent text and Expansions +type Parser struct { + input string // the string we are scanning + pos int // the current position +} + +// NewParser returns a new instance of a Parser +func NewParser(str string) *Parser { + return &Parser{ + input: str, + pos: 0, + } +} + +// Parse expansions out of the internal text and return them as a tree of Expressions +func (p *Parser) Parse() (Expression, error) { + return p.parseExpression() +} + +func (p *Parser) parseExpression(stop ...rune) (Expression, error) { + var expr Expression + var stopStr = string(stop) + + for { + c := p.peekRune() + if c == eof || strings.ContainsRune(stopStr, c) { + break + } + + // check for our escaped characters first, as we assume nothing subsequently is escaped + if strings.HasPrefix(p.input[p.pos:], `\\`) { + p.pos += 2 + expr = append(expr, ExpressionItem{Text: `\\`}) + continue + } else if strings.HasPrefix(p.input[p.pos:], `\$`) || strings.HasPrefix(p.input[p.pos:], `$$`) { + p.pos += 2 + expr = append(expr, ExpressionItem{Text: `$`}) + continue + } + + // Ignore bash shell expansions + if strings.HasPrefix(p.input[p.pos:], `$(`) { + p.pos += 2 + expr = append(expr, ExpressionItem{Text: `$(`}) + continue + } + + // If we run into a dollar sign and it's not the last char, it's an expansion + if c == '$' && p.pos < (len(p.input)-1) { + expansion, err := p.parseExpansion() + if err != nil { + return nil, err + } + expr = append(expr, ExpressionItem{Expansion: expansion}) + continue + } + + // nibble a character, otherwise if it's a \ or a $ we can loop + c = p.nextRune() + + // Scan as much as we can into text + text := p.scanUntil(func(r rune) bool { + return (r == '$' || r == '\\' || strings.ContainsRune(stopStr, r)) + }) + + expr = append(expr, ExpressionItem{Text: string(c) + text}) + } + + return expr, nil +} + +func (p *Parser) parseExpansion() (Expansion, error) { + if c := p.nextRune(); c != '$' { + return nil, fmt.Errorf("Expected expansion to start with $, got %c", c) + } + + // if we have an open brace, this is a brace expansion + if c := p.peekRune(); c == '{' { + return p.parseBraceExpansion() + } + + identifier, err := p.scanIdentifier() + if err != nil { + return nil, err + } + + return VariableExpansion{Identifier: identifier}, nil +} + +func (p *Parser) parseBraceExpansion() (Expansion, error) { + if c := p.nextRune(); c != '{' { + return nil, fmt.Errorf("Expected brace expansion to start with {, got %c", c) + } + + identifier, err := p.scanIdentifier() + if err != nil { + return nil, err + } + + if c := p.peekRune(); c == '}' { + _ = p.nextRune() + return VariableExpansion{Identifier: identifier}, nil + } + + var operator string + var exp Expansion + + // Parse an operator, some trickery is needed to handle : vs :- + if op1 := p.nextRune(); op1 == ':' { + if op2 := p.peekRune(); op2 == '-' { + _ = p.nextRune() + operator = ":-" + } else { + operator = ":" + } + } else if op1 == '?' || op1 == '-' { + operator = string(op1) + } else { + return nil, fmt.Errorf("Expected an operator, got %c", op1) + } + + switch operator { + case `:-`: + exp, err = p.parseEmptyValueExpansion(identifier) + if err != nil { + return nil, err + } + case `-`: + exp, err = p.parseUnsetValueExpansion(identifier) + if err != nil { + return nil, err + } + case `:`: + exp, err = p.parseSubstringExpansion(identifier) + if err != nil { + return nil, err + } + case `?`: + exp, err = p.parseRequiredExpansion(identifier) + if err != nil { + return nil, err + } + } + + if c := p.nextRune(); c != '}' { + return nil, fmt.Errorf("Expected brace expansion to end with }, got %c", c) + } + + return exp, nil +} + +func (p *Parser) parseEmptyValueExpansion(identifier string) (Expansion, error) { + // parse an expression (text and expansions) up until the end of the brace + expr, err := p.parseExpression('}') + if err != nil { + return nil, err + } + + return EmptyValueExpansion{Identifier: identifier, Content: expr}, nil +} + +func (p *Parser) parseUnsetValueExpansion(identifier string) (Expansion, error) { + expr, err := p.parseExpression('}') + if err != nil { + return nil, err + } + + return UnsetValueExpansion{Identifier: identifier, Content: expr}, nil +} + +func (p *Parser) parseSubstringExpansion(identifier string) (Expansion, error) { + offset := p.scanUntil(func(r rune) bool { + return r == ':' || r == '}' + }) + + offsetInt, err := strconv.Atoi(strings.TrimSpace(offset)) + if err != nil { + return nil, fmt.Errorf("Unable to parse offset: %v", err) + } + + if c := p.peekRune(); c == '}' { + return SubstringExpansion{Identifier: identifier, Offset: offsetInt}, nil + } + + _ = p.nextRune() + length := p.scanUntil(func(r rune) bool { + return r == '}' + }) + + lengthInt, err := strconv.Atoi(strings.TrimSpace(length)) + if err != nil { + return nil, fmt.Errorf("Unable to parse length: %v", err) + } + + return SubstringExpansion{Identifier: identifier, Offset: offsetInt, Length: lengthInt, HasLength: true}, nil +} + +func (p *Parser) parseRequiredExpansion(identifier string) (Expansion, error) { + expr, err := p.parseExpression('}') + if err != nil { + return nil, err + } + + return RequiredExpansion{Identifier: identifier, Message: expr}, nil +} + +func (p *Parser) scanUntil(f func(rune) bool) string { + start := p.pos + for int(p.pos) < len(p.input) { + c, size := utf8.DecodeRuneInString(p.input[p.pos:]) + if c == utf8.RuneError || f(c) { + break + } + p.pos += size + } + return p.input[start:p.pos] +} + +func (p *Parser) scanIdentifier() (string, error) { + if c := p.peekRune(); !unicode.IsLetter(c) { + return "", fmt.Errorf("Expected identifier to start with a letter, got %c", c) + } + var notIdentifierChar = func(r rune) bool { + return (!unicode.IsLetter(r) && !unicode.IsNumber(r) && r != '_') + } + return p.scanUntil(notIdentifierChar), nil +} + +func (p *Parser) nextRune() rune { + if int(p.pos) >= len(p.input) { + return eof + } + c, size := utf8.DecodeRuneInString(p.input[p.pos:]) + p.pos += size + return c +} + +func (p *Parser) peekRune() rune { + if int(p.pos) >= len(p.input) { + return eof + } + c, _ := utf8.DecodeRuneInString(p.input[p.pos:]) + return c +} diff --git a/vendor/github.com/chrismellard/docker-credential-acr-env/pkg/token/token.go b/vendor/github.com/chrismellard/docker-credential-acr-env/pkg/token/token.go index a76be1e4f..feff3e1a4 100644 --- a/vendor/github.com/chrismellard/docker-credential-acr-env/pkg/token/token.go +++ b/vendor/github.com/chrismellard/docker-credential-acr-env/pkg/token/token.go @@ -17,6 +17,7 @@ package token import ( "fmt" + "os" "github.com/Azure/go-autorest/autorest/adal" "github.com/Azure/go-autorest/autorest/azure/auth" @@ -62,11 +63,46 @@ func getServicePrincipalToken(settings auth.EnvironmentSettings, resource string return &adal.ServicePrincipalToken{}, fmt.Errorf("authentication method currently unsupported") } + // federated OIDC JWT assertion + jwt, err := jwtLookup() + if err == nil { + clientID, isPresent := os.LookupEnv("AZURE_CLIENT_ID") + if !isPresent { + return &adal.ServicePrincipalToken{}, fmt.Errorf("failed to get client id from environment") + } + tenantID, isPresent := os.LookupEnv("AZURE_TENANT_ID") + if !isPresent { + return &adal.ServicePrincipalToken{}, fmt.Errorf("failed to get client id from environment") + } + + oAuthConfig, err := adal.NewOAuthConfig(settings.Environment.ActiveDirectoryEndpoint, tenantID) + if err != nil { + return &adal.ServicePrincipalToken{}, fmt.Errorf("failed to initialise OAuthConfig - %w", err) + } + + return adal.NewServicePrincipalTokenFromFederatedToken(*oAuthConfig, clientID, *jwt, resource) + } + // 4. MSI - msiEndpoint, err := adal.GetMSIEndpoint() - if err != nil { - return &adal.ServicePrincipalToken{}, fmt.Errorf("unable to determine MSIEndpoint %w", err) + return adal.NewServicePrincipalTokenFromManagedIdentity(resource, &adal.ManagedIdentityOptions{ + ClientID: os.Getenv("AZURE_CLIENT_ID"), + }) +} + +func jwtLookup() (*string, error) { + jwt, isPresent := os.LookupEnv("AZURE_FEDERATED_TOKEN") + if isPresent { + return &jwt, nil + } + + if jwtFile, isPresent := os.LookupEnv("AZURE_FEDERATED_TOKEN_FILE"); isPresent { + jwtBytes, err := os.ReadFile(jwtFile) + if err != nil { + return nil, err + } + jwt = string(jwtBytes) + return &jwt, nil } - return adal.NewServicePrincipalTokenFromMSI(msiEndpoint, resource) + return nil, fmt.Errorf("no JWT found") } diff --git a/vendor/github.com/clbanning/mxj/v2/doc.go b/vendor/github.com/clbanning/mxj/v2/doc.go index bede31265..07ac098e2 100644 --- a/vendor/github.com/clbanning/mxj/v2/doc.go +++ b/vendor/github.com/clbanning/mxj/v2/doc.go @@ -14,6 +14,11 @@ Related Packages: checkxml: github.com/clbanning/checkxml provides functions for validating XML data. Notes: + 2022.11.28: v2.7 - add SetGlobalKeyMapPrefix to change default prefix, '#', for default keys + 2022.11.20: v2.6 - add NewMapForattedXmlSeq for XML docs formatted with whitespace character + 2021.02.02: v2.5 - add XmlCheckIsValid toggle to force checking that the encoded XML is valid + 2020.12.14: v2.4 - add XMLEscapeCharsDecoder to preserve XML escaped characters in Map values + 2020.10.28: v2.3 - add TrimWhiteSpace option 2020.05.01: v2.2 - optimize map to XML encoding for large XML docs. 2019.07.04: v2.0 - remove unnecessary methods - mv.XmlWriterRaw, mv.XmlIndentWriterRaw - for Map and MapSeq. 2019.07.04: Add MapSeq type and move associated functions and methods from Map to MapSeq. diff --git a/vendor/github.com/clbanning/mxj/v2/leafnode.go b/vendor/github.com/clbanning/mxj/v2/leafnode.go index cf413ebdd..1bc814fdc 100644 --- a/vendor/github.com/clbanning/mxj/v2/leafnode.go +++ b/vendor/github.com/clbanning/mxj/v2/leafnode.go @@ -44,7 +44,7 @@ func (mv Map) LeafNodes(no_attr ...bool) []LeafNode { func getLeafNodes(path, node string, mv interface{}, l *[]LeafNode, noattr bool) { // if stripping attributes, then also strip "#text" key - if !noattr || node != "#text" { + if !noattr || node != textK { if path != "" && node[:1] != "[" { path += "." } diff --git a/vendor/github.com/clbanning/mxj/v2/readme.md b/vendor/github.com/clbanning/mxj/v2/readme.md index 323a747d4..0e0a09a42 100644 --- a/vendor/github.com/clbanning/mxj/v2/readme.md +++ b/vendor/github.com/clbanning/mxj/v2/readme.md @@ -6,7 +6,7 @@ mxj supplants the legacy x2j and j2x packages. If you want the old syntax, use m

Installation

Using go.mod:
-go get github.com/clbanning/mxj/v2@v2.3.2
+go get github.com/clbanning/mxj/v2@v2.7	
 
@@ -42,6 +42,8 @@ For over a year I've wanted to refactor the XML-to-map[string]interface{} decode
 
 

Notices

+ 2022.11.28: v2.7 - add SetGlobalKeyMapPrefix to change default prefix, '#', for default keys + 2022.11.20: v2.6 - add NewMapForattedXmlSeq for XML docs formatted with whitespace character 2021.02.02: v2.5 - add XmlCheckIsValid toggle to force checking that the encoded XML is valid 2020.12.14: v2.4 - add XMLEscapeCharsDecoder to preserve XML escaped characters in Map values 2020.10.28: v2.3 - add TrimWhiteSpace option diff --git a/vendor/github.com/clbanning/mxj/v2/xml.go b/vendor/github.com/clbanning/mxj/v2/xml.go index 2ea1bc25a..b72a1460f 100644 --- a/vendor/github.com/clbanning/mxj/v2/xml.go +++ b/vendor/github.com/clbanning/mxj/v2/xml.go @@ -22,6 +22,30 @@ import ( "time" ) +var ( + textK = "#text" + seqK = "#seq" + commentK = "#comment" + attrK = "#attr" + directiveK = "#directive" + procinstK = "#procinst" + targetK = "#target" + instK = "#inst" +) + +// Support overriding default Map keys prefix + +func SetGlobalKeyMapPrefix(s string) { + textK = strings.ReplaceAll(textK, textK[0:1], s) + seqK = strings.ReplaceAll(seqK, seqK[0:1], s) + commentK = strings.ReplaceAll(commentK, commentK[0:1], s) + directiveK = strings.ReplaceAll(directiveK, directiveK[0:1], s) + procinstK = strings.ReplaceAll(procinstK, procinstK[0:1], s) + targetK = strings.ReplaceAll(targetK, targetK[0:1], s) + instK = strings.ReplaceAll(instK, instK[0:1], s) + attrK = strings.ReplaceAll(attrK, attrK[0:1], s) +} + // ------------------- NewMapXml & NewMapXmlReader ... ------------------------- // If XmlCharsetReader != nil, it will be used to decode the XML, if required. @@ -441,7 +465,7 @@ func xmlToMapParser(skey string, a []xml.Attr, p *xml.Decoder, r bool) (map[stri val.(map[string]interface{})["_seq"] = seq // will overwrite an "_seq" XML tag seq++ case interface{}: // a non-nil simple element: string, float64, bool - v := map[string]interface{}{"#text": val} + v := map[string]interface{}{textK: val} v["_seq"] = seq seq++ val = v @@ -479,7 +503,7 @@ func xmlToMapParser(skey string, a []xml.Attr, p *xml.Decoder, r bool) (map[stri } else if len(n) == 1 && len(na) > 0 { // it's a simple element w/ no attributes w/ subelements for _, v := range n { - na["#text"] = v + na[textK] = v } n[skey] = na } @@ -492,7 +516,7 @@ func xmlToMapParser(skey string, a []xml.Attr, p *xml.Decoder, r bool) (map[stri } if len(tt) > 0 { if len(na) > 0 || decodeSimpleValuesAsMap { - na["#text"] = cast(tt, r, "#text") + na[textK] = cast(tt, r, textK) } else if skey != "" { n[skey] = cast(tt, r, skey) } else { @@ -913,7 +937,8 @@ func (b *byteReader) Read(p []byte) (int, error) { func (b *byteReader) ReadByte() (byte, error) { _, err := b.r.Read(b.b) if len(b.b) > 0 { - return b.b[0], nil + // issue #38 + return b.b[0], err } var c byte return c, err @@ -1038,6 +1063,7 @@ func marshalMapToXmlIndent(doIndent bool, b *bytes.Buffer, key string, value int if doIndent { switch value.(type) { case []interface{}, []string: + // list processing handles indentation for all elements default: if _, err = b.WriteString(p.padding); err != nil { return err @@ -1113,7 +1139,7 @@ func marshalMapToXmlIndent(doIndent bool, b *bytes.Buffer, key string, value int // simple element? Note: '#text" is an invalid XML tag. isComplex := false - if v, ok := vv["#text"]; ok && n+1 == lenvv { + if v, ok := vv[textK]; ok && n+1 == lenvv { // just the value and attributes switch v.(type) { case string: @@ -1177,7 +1203,7 @@ func marshalMapToXmlIndent(doIndent bool, b *bytes.Buffer, key string, value int elemlist := make([][2]interface{}, len(vv)) n = 0 for k, v := range vv { - if k == "#text" { + if k == textK { // simple element handled above continue } diff --git a/vendor/github.com/clbanning/mxj/v2/xmlseq.go b/vendor/github.com/clbanning/mxj/v2/xmlseq.go index 80632bd3c..9732dec39 100644 --- a/vendor/github.com/clbanning/mxj/v2/xmlseq.go +++ b/vendor/github.com/clbanning/mxj/v2/xmlseq.go @@ -13,6 +13,7 @@ import ( "errors" "fmt" "io" + "regexp" "sort" "strings" ) @@ -81,6 +82,8 @@ var NO_ROOT = NoRoot // maintain backwards compatibility // ERRORS: // 1. If a NoRoot error, "no root key," is returned, check the initial map key for a "#comment", // "#directive" or #procinst" key. +// 2. Unmarshaling an XML doc that is formatted using the whitespace character, " ", will error, since +// Decoder.RawToken treats such occurances as significant. See NewMapFormattedXmlSeq(). func NewMapXmlSeq(xmlVal []byte, cast ...bool) (MapSeq, error) { var r bool if len(cast) == 1 { @@ -89,6 +92,28 @@ func NewMapXmlSeq(xmlVal []byte, cast ...bool) (MapSeq, error) { return xmlSeqToMap(xmlVal, r) } +// NewMapFormattedXmlSeq performs the same as NewMapXmlSeq but is useful for processing XML objects that +// are formatted using the whitespace character, " ". (The stdlib xml.Decoder, by default, treats all +// whitespace as significant; Decoder.Token() and Decoder.RawToken() will return strings of one or more +// whitespace characters and without alphanumeric or punctuation characters as xml.CharData values.) +// +// If you're processing such XML, then this will convert all occurrences of whitespace-only strings +// into an empty string, "", prior to parsing the XML - irrespective of whether the occurrence is +// formatting or is a actual element value. +func NewMapFormattedXmlSeq(xmlVal []byte, cast ...bool) (MapSeq, error) { + var c bool + if len(cast) == 1 { + c = cast[0] + } + + // Per PR #104 - clean out formatting characters so they don't show up in Decoder.RawToken() stream. + // NOTE: Also replaces element values that are solely comprised of formatting/whitespace characters + // with empty string, "". + r := regexp.MustCompile(`>[\n\t\r ]*<`) + xmlVal = r.ReplaceAll(xmlVal, []byte("><")) + return xmlSeqToMap(xmlVal, c) +} + // NewMpaXmlSeqReader returns next XML doc from an io.Reader as a MapSeq value. // NOTES: // 1. The 'xmlReader' will be parsed looking for an xml.StartElement, xml.Comment, etc., so BOM and other @@ -212,12 +237,12 @@ func xmlSeqToMapParser(skey string, a []xml.Attr, p *xml.Decoder, r bool) (map[s v.Value = escapeChars(v.Value) } if len(v.Name.Space) > 0 { - aa[v.Name.Space+`:`+v.Name.Local] = map[string]interface{}{"#text": cast(v.Value, r, ""), "#seq": i} + aa[v.Name.Space+`:`+v.Name.Local] = map[string]interface{}{textK: cast(v.Value, r, ""), seqK: i} } else { - aa[v.Name.Local] = map[string]interface{}{"#text": cast(v.Value, r, ""), "#seq": i} + aa[v.Name.Local] = map[string]interface{}{textK: cast(v.Value, r, ""), seqK: i} } } - na["#attr"] = aa + na[attrK] = aa } } @@ -285,10 +310,10 @@ func xmlSeqToMapParser(skey string, a []xml.Attr, p *xml.Decoder, r bool) (map[s // where all the "list" subelements are decoded into an array. switch val.(type) { case map[string]interface{}: - val.(map[string]interface{})["#seq"] = seq + val.(map[string]interface{})[seqK] = seq seq++ case interface{}: // a non-nil simple element: string, float64, bool - v := map[string]interface{}{"#text": val, "#seq": seq} + v := map[string]interface{}{textK: val, seqK: seq} seq++ val = v } @@ -355,42 +380,42 @@ func xmlSeqToMapParser(skey string, a []xml.Attr, p *xml.Decoder, r bool) (map[s } if len(tt) > 0 { // every simple element is a #text and has #seq associated with it - na["#text"] = cast(tt, r, "") - na["#seq"] = seq + na[textK] = cast(tt, r, "") + na[seqK] = seq seq++ } case xml.Comment: if n == nil { // no root 'key' - n = map[string]interface{}{"#comment": string(t.(xml.Comment))} + n = map[string]interface{}{commentK: string(t.(xml.Comment))} return n, NoRoot } cm := make(map[string]interface{}, 2) - cm["#text"] = string(t.(xml.Comment)) - cm["#seq"] = seq + cm[textK] = string(t.(xml.Comment)) + cm[seqK] = seq seq++ - na["#comment"] = cm + na[commentK] = cm case xml.Directive: if n == nil { // no root 'key' - n = map[string]interface{}{"#directive": string(t.(xml.Directive))} + n = map[string]interface{}{directiveK: string(t.(xml.Directive))} return n, NoRoot } dm := make(map[string]interface{}, 2) - dm["#text"] = string(t.(xml.Directive)) - dm["#seq"] = seq + dm[textK] = string(t.(xml.Directive)) + dm[seqK] = seq seq++ - na["#directive"] = dm + na[directiveK] = dm case xml.ProcInst: if n == nil { - na = map[string]interface{}{"#target": t.(xml.ProcInst).Target, "#inst": string(t.(xml.ProcInst).Inst)} - n = map[string]interface{}{"#procinst": na} + na = map[string]interface{}{targetK: t.(xml.ProcInst).Target, instK: string(t.(xml.ProcInst).Inst)} + n = map[string]interface{}{procinstK: na} return n, NoRoot } pm := make(map[string]interface{}, 3) - pm["#target"] = t.(xml.ProcInst).Target - pm["#inst"] = string(t.(xml.ProcInst).Inst) - pm["#seq"] = seq + pm[targetK] = t.(xml.ProcInst).Target + pm[instK] = string(t.(xml.ProcInst).Inst) + pm[seqK] = seq seq++ - na["#procinst"] = pm + na[procinstK] = pm default: // noop - shouldn't ever get here, now, since we handle all token types } @@ -580,7 +605,7 @@ func mapToXmlSeqIndent(doIndent bool, s *string, key string, value interface{}, if doIndent { *s += p.padding } - if key != "#comment" && key != "#directive" && key != "#procinst" { + if key != commentK && key != directiveK && key != procinstK { *s += `<` + key } } @@ -588,27 +613,27 @@ func mapToXmlSeqIndent(doIndent bool, s *string, key string, value interface{}, case map[string]interface{}: val := value.(map[string]interface{}) - if key == "#comment" { - *s += `` + if key == commentK { + *s += `` noEndTag = true break } - if key == "#directive" { - *s += `` + if key == directiveK { + *s += `` noEndTag = true break } - if key == "#procinst" { - *s += `` + if key == procinstK { + *s += `` noEndTag = true break } haveAttrs := false // process attributes first - if v, ok := val["#attr"].(map[string]interface{}); ok { + if v, ok := val[attrK].(map[string]interface{}); ok { // First, unroll the map[string]interface{} into a []keyval array. // Then sequence it. kv := make([]keyval, len(v)) @@ -621,21 +646,21 @@ func mapToXmlSeqIndent(doIndent bool, s *string, key string, value interface{}, // Now encode the attributes in original decoding sequence, using keyval array. for _, a := range kv { vv := a.v.(map[string]interface{}) - switch vv["#text"].(type) { + switch vv[textK].(type) { case string: if xmlEscapeChars { - ss = escapeChars(vv["#text"].(string)) + ss = escapeChars(vv[textK].(string)) } else { - ss = vv["#text"].(string) + ss = vv[textK].(string) } *s += ` ` + a.k + `="` + ss + `"` case float64, bool, int, int32, int64, float32: - *s += ` ` + a.k + `="` + fmt.Sprintf("%v", vv["#text"]) + `"` + *s += ` ` + a.k + `="` + fmt.Sprintf("%v", vv[textK]) + `"` case []byte: if xmlEscapeChars { - ss = escapeChars(string(vv["#text"].([]byte))) + ss = escapeChars(string(vv[textK].([]byte))) } else { - ss = string(vv["#text"].([]byte)) + ss = string(vv[textK].([]byte)) } *s += ` ` + a.k + `="` + ss + `"` default: @@ -647,8 +672,8 @@ func mapToXmlSeqIndent(doIndent bool, s *string, key string, value interface{}, // simple element? // every map value has, at least, "#seq" and, perhaps, "#text" and/or "#attr" - _, seqOK := val["#seq"] // have key - if v, ok := val["#text"]; ok && ((len(val) == 3 && haveAttrs) || (len(val) == 2 && !haveAttrs)) && seqOK { + _, seqOK := val[seqK] // have key + if v, ok := val[textK]; ok && ((len(val) == 3 && haveAttrs) || (len(val) == 2 && !haveAttrs)) && seqOK { if stmp, ok := v.(string); ok && stmp != "" { if xmlEscapeChars { stmp = escapeChars(stmp) @@ -669,10 +694,10 @@ func mapToXmlSeqIndent(doIndent bool, s *string, key string, value interface{}, // 'kv' will hold everything that needs to be written kv := make([]keyval, 0) for k, v := range val { - if k == "#attr" { // already processed + if k == attrK { // already processed continue } - if k == "#seq" { // ignore - just for sorting + if k == seqK { // ignore - just for sorting continue } switch v.(type) { @@ -845,16 +870,16 @@ func (e elemListSeq) Less(i, j int) bool { var iseq, jseq int var fiseq, fjseq float64 var ok bool - if iseq, ok = e[i].v.(map[string]interface{})["#seq"].(int); !ok { - if fiseq, ok = e[i].v.(map[string]interface{})["#seq"].(float64); ok { + if iseq, ok = e[i].v.(map[string]interface{})[seqK].(int); !ok { + if fiseq, ok = e[i].v.(map[string]interface{})[seqK].(float64); ok { iseq = int(fiseq) } else { iseq = 9999999 } } - if jseq, ok = e[j].v.(map[string]interface{})["#seq"].(int); !ok { - if fjseq, ok = e[j].v.(map[string]interface{})["#seq"].(float64); ok { + if jseq, ok = e[j].v.(map[string]interface{})[seqK].(int); !ok { + if fjseq, ok = e[j].v.(map[string]interface{})[seqK].(float64); ok { jseq = int(fjseq) } else { jseq = 9999999 diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist.go index 8cd4e333b..83d7cdadd 100644 --- a/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist.go +++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist.go @@ -9,7 +9,7 @@ import ( fp "github.com/cloudflare/circl/math/fp448" ) -// twistCurve is -x^2+y^2=1-39082x^2y^2 and is 4-isogeneous to Goldilocks. +// twistCurve is -x^2+y^2=1-39082x^2y^2 and is 4-isogenous to Goldilocks. type twistCurve struct{} // Identity returns the identity point. diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/keccakf.go b/vendor/github.com/cloudflare/circl/internal/sha3/keccakf.go index ab19d0ad1..1755fd1e6 100644 --- a/vendor/github.com/cloudflare/circl/internal/sha3/keccakf.go +++ b/vendor/github.com/cloudflare/circl/internal/sha3/keccakf.go @@ -6,13 +6,21 @@ package sha3 // KeccakF1600 applies the Keccak permutation to a 1600b-wide // state represented as a slice of 25 uint64s. +// If turbo is true, applies the 12-round variant instead of the +// regular 24-round variant. // nolint:funlen -func KeccakF1600(a *[25]uint64) { +func KeccakF1600(a *[25]uint64, turbo bool) { // Implementation translated from Keccak-inplace.c // in the keccak reference code. var t, bc0, bc1, bc2, bc3, bc4, d0, d1, d2, d3, d4 uint64 - for i := 0; i < 24; i += 4 { + i := 0 + + if turbo { + i = 12 + } + + for ; i < 24; i += 4 { // Combines the 5 steps in each round into 2 steps. // Unrolls 4 rounds per loop and spreads some steps across rounds. diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/sha3.go b/vendor/github.com/cloudflare/circl/internal/sha3/sha3.go index b35cd006b..a0df5aa6c 100644 --- a/vendor/github.com/cloudflare/circl/internal/sha3/sha3.go +++ b/vendor/github.com/cloudflare/circl/internal/sha3/sha3.go @@ -51,6 +51,7 @@ type State struct { // Specific to SHA-3 and SHAKE. outputLen int // the default output size in bytes state spongeDirection // whether the sponge is absorbing or squeezing + turbo bool // Whether we're using 12 rounds instead of 24 } // BlockSize returns the rate of sponge underlying this hash function. @@ -86,11 +87,11 @@ func (d *State) permute() { xorIn(d, d.buf()) d.bufe = 0 d.bufo = 0 - KeccakF1600(&d.a) + KeccakF1600(&d.a, d.turbo) case spongeSqueezing: // If we're squeezing, we need to apply the permutation before // copying more output. - KeccakF1600(&d.a) + KeccakF1600(&d.a, d.turbo) d.bufe = d.rate d.bufo = 0 copyOut(d, d.buf()) @@ -136,7 +137,7 @@ func (d *State) Write(p []byte) (written int, err error) { // The fast path; absorb a full "rate" bytes of input and apply the permutation. xorIn(d, p[:d.rate]) p = p[d.rate:] - KeccakF1600(&d.a) + KeccakF1600(&d.a, d.turbo) } else { // The slow path; buffer the input until we can fill the sponge, and then xor it in. todo := d.rate - bufl @@ -193,3 +194,7 @@ func (d *State) Sum(in []byte) []byte { _, _ = dup.Read(hash) return append(in, hash...) } + +func (d *State) IsAbsorbing() bool { + return d.state == spongeAbsorbing +} diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/shake.go b/vendor/github.com/cloudflare/circl/internal/sha3/shake.go index b92c5b7d7..77817f758 100644 --- a/vendor/github.com/cloudflare/circl/internal/sha3/shake.go +++ b/vendor/github.com/cloudflare/circl/internal/sha3/shake.go @@ -57,6 +57,17 @@ func NewShake128() State { return State{rate: rate128, dsbyte: dsbyteShake} } +// NewTurboShake128 creates a new TurboSHAKE128 variable-output-length ShakeHash. +// Its generic security strength is 128 bits against all attacks if at +// least 32 bytes of its output are used. +// D is the domain separation byte and must be between 0x01 and 0x7f inclusive. +func NewTurboShake128(D byte) State { + if D == 0 || D > 0x7f { + panic("turboshake: D out of range") + } + return State{rate: rate128, dsbyte: D, turbo: true} +} + // NewShake256 creates a new SHAKE256 variable-output-length ShakeHash. // Its generic security strength is 256 bits against all attacks if // at least 64 bytes of its output are used. @@ -64,6 +75,17 @@ func NewShake256() State { return State{rate: rate256, dsbyte: dsbyteShake} } +// NewTurboShake256 creates a new TurboSHAKE256 variable-output-length ShakeHash. +// Its generic security strength is 256 bits against all attacks if +// at least 64 bytes of its output are used. +// D is the domain separation byte and must be between 0x01 and 0x7f inclusive. +func NewTurboShake256(D byte) State { + if D == 0 || D > 0x7f { + panic("turboshake: D out of range") + } + return State{rate: rate256, dsbyte: D, turbo: true} +} + // ShakeSum128 writes an arbitrary-length digest of data into hash. func ShakeSum128(hash, data []byte) { h := NewShake128() @@ -77,3 +99,21 @@ func ShakeSum256(hash, data []byte) { _, _ = h.Write(data) _, _ = h.Read(hash) } + +// TurboShakeSum128 writes an arbitrary-length digest of data into hash. +func TurboShakeSum128(hash, data []byte, D byte) { + h := NewTurboShake128(D) + _, _ = h.Write(data) + _, _ = h.Read(hash) +} + +// TurboShakeSum256 writes an arbitrary-length digest of data into hash. +func TurboShakeSum256(hash, data []byte, D byte) { + h := NewTurboShake256(D) + _, _ = h.Write(data) + _, _ = h.Read(hash) +} + +func (d *State) SwitchDS(D byte) { + d.dsbyte = D +} diff --git a/vendor/github.com/cloudflare/circl/math/primes.go b/vendor/github.com/cloudflare/circl/math/primes.go new file mode 100644 index 000000000..158fd83a7 --- /dev/null +++ b/vendor/github.com/cloudflare/circl/math/primes.go @@ -0,0 +1,34 @@ +package math + +import ( + "crypto/rand" + "io" + "math/big" +) + +// IsSafePrime reports whether p is (probably) a safe prime. +// The prime p=2*q+1 is safe prime if both p and q are primes. +// Note that ProbablyPrime is not suitable for judging primes +// that an adversary may have crafted to fool the test. +func IsSafePrime(p *big.Int) bool { + pdiv2 := new(big.Int).Rsh(p, 1) + return p.ProbablyPrime(20) && pdiv2.ProbablyPrime(20) +} + +// SafePrime returns a number of the given bit length that is a safe prime with high probability. +// The number returned p=2*q+1 is a safe prime if both p and q are primes. +// SafePrime will return error for any error returned by rand.Read or if bits < 2. +func SafePrime(random io.Reader, bits int) (*big.Int, error) { + one := big.NewInt(1) + p := new(big.Int) + for { + q, err := rand.Prime(random, bits-1) + if err != nil { + return nil, err + } + p.Lsh(q, 1).Add(p, one) + if p.ProbablyPrime(20) { + return p, nil + } + } +} diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/ed25519.go b/vendor/github.com/cloudflare/circl/sign/ed25519/ed25519.go index 08ca65d79..2c73c26fb 100644 --- a/vendor/github.com/cloudflare/circl/sign/ed25519/ed25519.go +++ b/vendor/github.com/cloudflare/circl/sign/ed25519/ed25519.go @@ -1,7 +1,7 @@ // Package ed25519 implements Ed25519 signature scheme as described in RFC-8032. // // This package provides optimized implementations of the three signature -// variants and maintaining closer compatiblilty with crypto/ed25519. +// variants and maintaining closer compatibility with crypto/ed25519. // // | Scheme Name | Sign Function | Verification | Context | // |-------------|-------------------|---------------|-------------------| diff --git a/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go b/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go index 539933b3d..b1e3f7e3f 100644 --- a/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go +++ b/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go @@ -8,7 +8,7 @@ import ( "crypto/rsa" "errors" "fmt" - "io/ioutil" + "io" "net/http" "sync" "time" @@ -159,7 +159,7 @@ func (r *RemoteKeySet) verify(ctx context.Context, jws *jose.JSONWebSignature) ( // https://openid.net/specs/openid-connect-core-1_0.html#RotateSigKeys keys, err := r.keysFromRemote(ctx) if err != nil { - return nil, fmt.Errorf("fetching keys %v", err) + return nil, fmt.Errorf("fetching keys %w", err) } for _, key := range keys { @@ -228,11 +228,11 @@ func (r *RemoteKeySet) updateKeys() ([]jose.JSONWebKey, error) { resp, err := doRequest(r.ctx, req) if err != nil { - return nil, fmt.Errorf("oidc: get keys failed %v", err) + return nil, fmt.Errorf("oidc: get keys failed %w", err) } defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("unable to read response body: %v", err) } diff --git a/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go b/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go index b159d1ccd..6e2b0e567 100644 --- a/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go +++ b/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go @@ -10,7 +10,7 @@ import ( "errors" "fmt" "hash" - "io/ioutil" + "io" "mime" "net/http" "strings" @@ -211,7 +211,7 @@ func NewProvider(ctx context.Context, issuer string) (*Provider, error) { } defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("unable to read response body: %v", err) } @@ -332,7 +332,7 @@ func (p *Provider) UserInfo(ctx context.Context, tokenSource oauth2.TokenSource) return nil, err } defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return nil, err } diff --git a/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go b/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go index 3e5ffbc76..0bca49a89 100644 --- a/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go +++ b/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go @@ -7,7 +7,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "net/http" "strings" "time" @@ -182,7 +182,7 @@ func resolveDistributedClaim(ctx context.Context, verifier *IDTokenVerifier, src } defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("unable to read response body: %v", err) } diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE new file mode 100644 index 000000000..d2d1dd933 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE @@ -0,0 +1,17 @@ +ISC License + +Copyright (c) 2013-2017 The btcsuite developers +Copyright (c) 2015-2020 The Decred developers +Copyright (c) 2017 The Lightning Network Developers + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md new file mode 100644 index 000000000..b84bcdb77 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md @@ -0,0 +1,72 @@ +secp256k1 +========= + +[![Build Status](https://github.com/decred/dcrd/workflows/Build%20and%20Test/badge.svg)](https://github.com/decred/dcrd/actions) +[![ISC License](https://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) +[![Doc](https://img.shields.io/badge/doc-reference-blue.svg)](https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v4) + +Package secp256k1 implements optimized secp256k1 elliptic curve operations. + +This package provides an optimized pure Go implementation of elliptic curve +cryptography operations over the secp256k1 curve as well as data structures and +functions for working with public and private secp256k1 keys. See +https://www.secg.org/sec2-v2.pdf for details on the standard. + +In addition, sub packages are provided to produce, verify, parse, and serialize +ECDSA signatures and EC-Schnorr-DCRv0 (a custom Schnorr-based signature scheme +specific to Decred) signatures. See the README.md files in the relevant sub +packages for more details about those aspects. + +An overview of the features provided by this package are as follows: + +- Private key generation, serialization, and parsing +- Public key generation, serialization and parsing per ANSI X9.62-1998 + - Parses uncompressed, compressed, and hybrid public keys + - Serializes uncompressed and compressed public keys +- Specialized types for performing optimized and constant time field operations + - `FieldVal` type for working modulo the secp256k1 field prime + - `ModNScalar` type for working modulo the secp256k1 group order +- Elliptic curve operations in Jacobian projective coordinates + - Point addition + - Point doubling + - Scalar multiplication with an arbitrary point + - Scalar multiplication with the base point (group generator) +- Point decompression from a given x coordinate +- Nonce generation via RFC6979 with support for extra data and version + information that can be used to prevent nonce reuse between signing algorithms + +It also provides an implementation of the Go standard library `crypto/elliptic` +`Curve` interface via the `S256` function so that it may be used with other +packages in the standard library such as `crypto/tls`, `crypto/x509`, and +`crypto/ecdsa`. However, in the case of ECDSA, it is highly recommended to use +the `ecdsa` sub package of this package instead since it is optimized +specifically for secp256k1 and is significantly faster as a result. + +Although this package was primarily written for dcrd, it has intentionally been +designed so it can be used as a standalone package for any projects needing to +use optimized secp256k1 elliptic curve cryptography. + +Finally, a comprehensive suite of tests is provided to provide a high level of +quality assurance. + +## secp256k1 use in Decred + +At the time of this writing, the primary public key cryptography in widespread +use on the Decred network used to secure coins is based on elliptic curves +defined by the secp256k1 domain parameters. + +## Installation and Updating + +This package is part of the `github.com/decred/dcrd/dcrec/secp256k1/v4` module. +Use the standard go tooling for working with modules to incorporate it. + +## Examples + +* [Encryption](https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v4#example-package-EncryptDecryptMessage) + Demonstrates encrypting and decrypting a message using a shared key derived + through ECDHE. + +## License + +Package secp256k1 is licensed under the [copyfree](http://copyfree.org) ISC +License. diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go new file mode 100644 index 000000000..bb0b41fda --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go @@ -0,0 +1,18 @@ +// Copyright (c) 2015 The btcsuite developers +// Copyright (c) 2015-2022 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// Auto-generated file (see genprecomps.go) +// DO NOT EDIT + +var compressedBytePoints = "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" + +// Set accessor to a real function. +func init() { + compressedBytePointsFn = func() string { + return compressedBytePoints + } +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go new file mode 100644 index 000000000..c9d47f307 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go @@ -0,0 +1,1272 @@ +// Copyright (c) 2015-2022 The Decred developers +// Copyright 2013-2014 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + "encoding/hex" + "math/bits" +) + +// References: +// [SECG]: Recommended Elliptic Curve Domain Parameters +// https://www.secg.org/sec2-v2.pdf +// +// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone) +// +// [BRID]: On Binary Representations of Integers with Digits -1, 0, 1 +// (Prodinger, Helmut) +// +// [STWS]: Secure-TWS: Authenticating Node to Multi-user Communication in +// Shared Sensor Networks (Oliveira, Leonardo B. et al) + +// All group operations are performed using Jacobian coordinates. For a given +// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1) +// where x = x1/z1^2 and y = y1/z1^3. + +// hexToFieldVal converts the passed hex string into a FieldVal and will panic +// if there is an error. This is only provided for the hard-coded constants so +// errors in the source code can be detected. It will only (and must only) be +// called with hard-coded values. +func hexToFieldVal(s string) *FieldVal { + b, err := hex.DecodeString(s) + if err != nil { + panic("invalid hex in source file: " + s) + } + var f FieldVal + if overflow := f.SetByteSlice(b); overflow { + panic("hex in source file overflows mod P: " + s) + } + return &f +} + +// hexToModNScalar converts the passed hex string into a ModNScalar and will +// panic if there is an error. This is only provided for the hard-coded +// constants so errors in the source code can be detected. It will only (and +// must only) be called with hard-coded values. +func hexToModNScalar(s string) *ModNScalar { + var isNegative bool + if len(s) > 0 && s[0] == '-' { + isNegative = true + s = s[1:] + } + if len(s)%2 != 0 { + s = "0" + s + } + b, err := hex.DecodeString(s) + if err != nil { + panic("invalid hex in source file: " + s) + } + var scalar ModNScalar + if overflow := scalar.SetByteSlice(b); overflow { + panic("hex in source file overflows mod N scalar: " + s) + } + if isNegative { + scalar.Negate() + } + return &scalar +} + +var ( + // The following constants are used to accelerate scalar point + // multiplication through the use of the endomorphism: + // + // φ(Q) ⟼ λ*Q = (β*Q.x mod p, Q.y) + // + // See the code in the deriveEndomorphismParams function in genprecomps.go + // for details on their derivation. + // + // Additionally, see the scalar multiplication function in this file for + // details on how they are used. + endoNegLambda = hexToModNScalar("-5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72") + endoBeta = hexToFieldVal("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee") + endoNegB1 = hexToModNScalar("e4437ed6010e88286f547fa90abfe4c3") + endoNegB2 = hexToModNScalar("-3086d221a7d46bcde86c90e49284eb15") + endoZ1 = hexToModNScalar("3086d221a7d46bcde86c90e49284eb153daa8a1471e8ca7f") + endoZ2 = hexToModNScalar("e4437ed6010e88286f547fa90abfe4c4221208ac9df506c6") + + // Alternatively, the following parameters are valid as well, however, + // benchmarks show them to be about 2% slower in practice. + // endoNegLambda = hexToModNScalar("-ac9c52b33fa3cf1f5ad9e3fd77ed9ba4a880b9fc8ec739c2e0cfc810b51283ce") + // endoBeta = hexToFieldVal("851695d49a83f8ef919bb86153cbcb16630fb68aed0a766a3ec693d68e6afa40") + // endoNegB1 = hexToModNScalar("3086d221a7d46bcde86c90e49284eb15") + // endoNegB2 = hexToModNScalar("-114ca50f7a8e2f3f657c1108d9d44cfd8") + // endoZ1 = hexToModNScalar("114ca50f7a8e2f3f657c1108d9d44cfd95fbc92c10fddd145") + // endoZ2 = hexToModNScalar("3086d221a7d46bcde86c90e49284eb153daa8a1471e8ca7f") +) + +// JacobianPoint is an element of the group formed by the secp256k1 curve in +// Jacobian projective coordinates and thus represents a point on the curve. +type JacobianPoint struct { + // The X coordinate in Jacobian projective coordinates. The affine point is + // X/z^2. + X FieldVal + + // The Y coordinate in Jacobian projective coordinates. The affine point is + // Y/z^3. + Y FieldVal + + // The Z coordinate in Jacobian projective coordinates. + Z FieldVal +} + +// MakeJacobianPoint returns a Jacobian point with the provided X, Y, and Z +// coordinates. +func MakeJacobianPoint(x, y, z *FieldVal) JacobianPoint { + var p JacobianPoint + p.X.Set(x) + p.Y.Set(y) + p.Z.Set(z) + return p +} + +// Set sets the Jacobian point to the provided point. +func (p *JacobianPoint) Set(other *JacobianPoint) { + p.X.Set(&other.X) + p.Y.Set(&other.Y) + p.Z.Set(&other.Z) +} + +// ToAffine reduces the Z value of the existing point to 1 effectively +// making it an affine coordinate in constant time. The point will be +// normalized. +func (p *JacobianPoint) ToAffine() { + // Inversions are expensive and both point addition and point doubling + // are faster when working with points that have a z value of one. So, + // if the point needs to be converted to affine, go ahead and normalize + // the point itself at the same time as the calculation is the same. + var zInv, tempZ FieldVal + zInv.Set(&p.Z).Inverse() // zInv = Z^-1 + tempZ.SquareVal(&zInv) // tempZ = Z^-2 + p.X.Mul(&tempZ) // X = X/Z^2 (mag: 1) + p.Y.Mul(tempZ.Mul(&zInv)) // Y = Y/Z^3 (mag: 1) + p.Z.SetInt(1) // Z = 1 (mag: 1) + + // Normalize the x and y values. + p.X.Normalize() + p.Y.Normalize() +} + +// addZ1AndZ2EqualsOne adds two Jacobian points that are already known to have +// z values of 1 and stores the result in the provided result param. That is to +// say result = p1 + p2. It performs faster addition than the generic add +// routine since less arithmetic is needed due to the ability to avoid the z +// value multiplications. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func addZ1AndZ2EqualsOne(p1, p2, result *JacobianPoint) { + // To compute the point addition efficiently, this implementation splits + // the equation into intermediate elements which are used to minimize + // the number of field multiplications using the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl + // + // In particular it performs the calculations using the following: + // H = X2-X1, HH = H^2, I = 4*HH, J = H*I, r = 2*(Y2-Y1), V = X1*I + // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*Y1*J, Z3 = 2*H + // + // This results in a cost of 4 field multiplications, 2 field squarings, + // 6 field additions, and 5 integer multiplications. + x1, y1 := &p1.X, &p1.Y + x2, y2 := &p2.X, &p2.Y + x3, y3, z3 := &result.X, &result.Y, &result.Z + + // When the x coordinates are the same for two points on the curve, the + // y coordinates either must be the same, in which case it is point + // doubling, or they are opposite and the result is the point at + // infinity per the group law for elliptic curve cryptography. + if x1.Equals(x2) { + if y1.Equals(y2) { + // Since x1 == x2 and y1 == y2, point doubling must be + // done, otherwise the addition would end up dividing + // by zero. + DoubleNonConst(p1, result) + return + } + + // Since x1 == x2 and y1 == -y2, the sum is the point at + // infinity per the group law. + x3.SetInt(0) + y3.SetInt(0) + z3.SetInt(0) + return + } + + // Calculate X3, Y3, and Z3 according to the intermediate elements + // breakdown above. + var h, i, j, r, v FieldVal + var negJ, neg2V, negX3 FieldVal + h.Set(x1).Negate(1).Add(x2) // H = X2-X1 (mag: 3) + i.SquareVal(&h).MulInt(4) // I = 4*H^2 (mag: 4) + j.Mul2(&h, &i) // J = H*I (mag: 1) + r.Set(y1).Negate(1).Add(y2).MulInt(2) // r = 2*(Y2-Y1) (mag: 6) + v.Mul2(x1, &i) // V = X1*I (mag: 1) + negJ.Set(&j).Negate(1) // negJ = -J (mag: 2) + neg2V.Set(&v).MulInt(2).Negate(2) // neg2V = -(2*V) (mag: 3) + x3.Set(&r).Square().Add(&negJ).Add(&neg2V) // X3 = r^2-J-2*V (mag: 6) + negX3.Set(x3).Negate(6) // negX3 = -X3 (mag: 7) + j.Mul(y1).MulInt(2).Negate(2) // J = -(2*Y1*J) (mag: 3) + y3.Set(&v).Add(&negX3).Mul(&r).Add(&j) // Y3 = r*(V-X3)-2*Y1*J (mag: 4) + z3.Set(&h).MulInt(2) // Z3 = 2*H (mag: 6) + + // Normalize the resulting field values as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// addZ1EqualsZ2 adds two Jacobian points that are already known to have the +// same z value and stores the result in the provided result param. That is to +// say result = p1 + p2. It performs faster addition than the generic add +// routine since less arithmetic is needed due to the known equivalence. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func addZ1EqualsZ2(p1, p2, result *JacobianPoint) { + // To compute the point addition efficiently, this implementation splits + // the equation into intermediate elements which are used to minimize + // the number of field multiplications using a slightly modified version + // of the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-zadd-2007-m + // + // In particular it performs the calculations using the following: + // A = X2-X1, B = A^2, C=Y2-Y1, D = C^2, E = X1*B, F = X2*B + // X3 = D-E-F, Y3 = C*(E-X3)-Y1*(F-E), Z3 = Z1*A + // + // This results in a cost of 5 field multiplications, 2 field squarings, + // 9 field additions, and 0 integer multiplications. + x1, y1, z1 := &p1.X, &p1.Y, &p1.Z + x2, y2 := &p2.X, &p2.Y + x3, y3, z3 := &result.X, &result.Y, &result.Z + + // When the x coordinates are the same for two points on the curve, the + // y coordinates either must be the same, in which case it is point + // doubling, or they are opposite and the result is the point at + // infinity per the group law for elliptic curve cryptography. + if x1.Equals(x2) { + if y1.Equals(y2) { + // Since x1 == x2 and y1 == y2, point doubling must be + // done, otherwise the addition would end up dividing + // by zero. + DoubleNonConst(p1, result) + return + } + + // Since x1 == x2 and y1 == -y2, the sum is the point at + // infinity per the group law. + x3.SetInt(0) + y3.SetInt(0) + z3.SetInt(0) + return + } + + // Calculate X3, Y3, and Z3 according to the intermediate elements + // breakdown above. + var a, b, c, d, e, f FieldVal + var negX1, negY1, negE, negX3 FieldVal + negX1.Set(x1).Negate(1) // negX1 = -X1 (mag: 2) + negY1.Set(y1).Negate(1) // negY1 = -Y1 (mag: 2) + a.Set(&negX1).Add(x2) // A = X2-X1 (mag: 3) + b.SquareVal(&a) // B = A^2 (mag: 1) + c.Set(&negY1).Add(y2) // C = Y2-Y1 (mag: 3) + d.SquareVal(&c) // D = C^2 (mag: 1) + e.Mul2(x1, &b) // E = X1*B (mag: 1) + negE.Set(&e).Negate(1) // negE = -E (mag: 2) + f.Mul2(x2, &b) // F = X2*B (mag: 1) + x3.Add2(&e, &f).Negate(2).Add(&d) // X3 = D-E-F (mag: 4) + negX3.Set(x3).Negate(4) // negX3 = -X3 (mag: 5) + y3.Set(y1).Mul(f.Add(&negE)).Negate(1) // Y3 = -(Y1*(F-E)) (mag: 2) + y3.Add(e.Add(&negX3).Mul(&c)) // Y3 = C*(E-X3)+Y3 (mag: 3) + z3.Mul2(z1, &a) // Z3 = Z1*A (mag: 1) + + // Normalize the resulting field values as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// addZ2EqualsOne adds two Jacobian points when the second point is already +// known to have a z value of 1 (and the z value for the first point is not 1) +// and stores the result in the provided result param. That is to say result = +// p1 + p2. It performs faster addition than the generic add routine since +// less arithmetic is needed due to the ability to avoid multiplications by the +// second point's z value. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func addZ2EqualsOne(p1, p2, result *JacobianPoint) { + // To compute the point addition efficiently, this implementation splits + // the equation into intermediate elements which are used to minimize + // the number of field multiplications using the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl + // + // In particular it performs the calculations using the following: + // Z1Z1 = Z1^2, U2 = X2*Z1Z1, S2 = Y2*Z1*Z1Z1, H = U2-X1, HH = H^2, + // I = 4*HH, J = H*I, r = 2*(S2-Y1), V = X1*I + // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*Y1*J, Z3 = (Z1+H)^2-Z1Z1-HH + // + // This results in a cost of 7 field multiplications, 4 field squarings, + // 9 field additions, and 4 integer multiplications. + x1, y1, z1 := &p1.X, &p1.Y, &p1.Z + x2, y2 := &p2.X, &p2.Y + x3, y3, z3 := &result.X, &result.Y, &result.Z + + // When the x coordinates are the same for two points on the curve, the + // y coordinates either must be the same, in which case it is point + // doubling, or they are opposite and the result is the point at + // infinity per the group law for elliptic curve cryptography. Since + // any number of Jacobian coordinates can represent the same affine + // point, the x and y values need to be converted to like terms. Due to + // the assumption made for this function that the second point has a z + // value of 1 (z2=1), the first point is already "converted". + var z1z1, u2, s2 FieldVal + z1z1.SquareVal(z1) // Z1Z1 = Z1^2 (mag: 1) + u2.Set(x2).Mul(&z1z1).Normalize() // U2 = X2*Z1Z1 (mag: 1) + s2.Set(y2).Mul(&z1z1).Mul(z1).Normalize() // S2 = Y2*Z1*Z1Z1 (mag: 1) + if x1.Equals(&u2) { + if y1.Equals(&s2) { + // Since x1 == x2 and y1 == y2, point doubling must be + // done, otherwise the addition would end up dividing + // by zero. + DoubleNonConst(p1, result) + return + } + + // Since x1 == x2 and y1 == -y2, the sum is the point at + // infinity per the group law. + x3.SetInt(0) + y3.SetInt(0) + z3.SetInt(0) + return + } + + // Calculate X3, Y3, and Z3 according to the intermediate elements + // breakdown above. + var h, hh, i, j, r, rr, v FieldVal + var negX1, negY1, negX3 FieldVal + negX1.Set(x1).Negate(1) // negX1 = -X1 (mag: 2) + h.Add2(&u2, &negX1) // H = U2-X1 (mag: 3) + hh.SquareVal(&h) // HH = H^2 (mag: 1) + i.Set(&hh).MulInt(4) // I = 4 * HH (mag: 4) + j.Mul2(&h, &i) // J = H*I (mag: 1) + negY1.Set(y1).Negate(1) // negY1 = -Y1 (mag: 2) + r.Set(&s2).Add(&negY1).MulInt(2) // r = 2*(S2-Y1) (mag: 6) + rr.SquareVal(&r) // rr = r^2 (mag: 1) + v.Mul2(x1, &i) // V = X1*I (mag: 1) + x3.Set(&v).MulInt(2).Add(&j).Negate(3) // X3 = -(J+2*V) (mag: 4) + x3.Add(&rr) // X3 = r^2+X3 (mag: 5) + negX3.Set(x3).Negate(5) // negX3 = -X3 (mag: 6) + y3.Set(y1).Mul(&j).MulInt(2).Negate(2) // Y3 = -(2*Y1*J) (mag: 3) + y3.Add(v.Add(&negX3).Mul(&r)) // Y3 = r*(V-X3)+Y3 (mag: 4) + z3.Add2(z1, &h).Square() // Z3 = (Z1+H)^2 (mag: 1) + z3.Add(z1z1.Add(&hh).Negate(2)) // Z3 = Z3-(Z1Z1+HH) (mag: 4) + + // Normalize the resulting field values as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// addGeneric adds two Jacobian points without any assumptions about the z +// values of the two points and stores the result in the provided result param. +// That is to say result = p1 + p2. It is the slowest of the add routines due +// to requiring the most arithmetic. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func addGeneric(p1, p2, result *JacobianPoint) { + // To compute the point addition efficiently, this implementation splits + // the equation into intermediate elements which are used to minimize + // the number of field multiplications using the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl + // + // In particular it performs the calculations using the following: + // Z1Z1 = Z1^2, Z2Z2 = Z2^2, U1 = X1*Z2Z2, U2 = X2*Z1Z1, S1 = Y1*Z2*Z2Z2 + // S2 = Y2*Z1*Z1Z1, H = U2-U1, I = (2*H)^2, J = H*I, r = 2*(S2-S1) + // V = U1*I + // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*S1*J, Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H + // + // This results in a cost of 11 field multiplications, 5 field squarings, + // 9 field additions, and 4 integer multiplications. + x1, y1, z1 := &p1.X, &p1.Y, &p1.Z + x2, y2, z2 := &p2.X, &p2.Y, &p2.Z + x3, y3, z3 := &result.X, &result.Y, &result.Z + + // When the x coordinates are the same for two points on the curve, the + // y coordinates either must be the same, in which case it is point + // doubling, or they are opposite and the result is the point at + // infinity. Since any number of Jacobian coordinates can represent the + // same affine point, the x and y values need to be converted to like + // terms. + var z1z1, z2z2, u1, u2, s1, s2 FieldVal + z1z1.SquareVal(z1) // Z1Z1 = Z1^2 (mag: 1) + z2z2.SquareVal(z2) // Z2Z2 = Z2^2 (mag: 1) + u1.Set(x1).Mul(&z2z2).Normalize() // U1 = X1*Z2Z2 (mag: 1) + u2.Set(x2).Mul(&z1z1).Normalize() // U2 = X2*Z1Z1 (mag: 1) + s1.Set(y1).Mul(&z2z2).Mul(z2).Normalize() // S1 = Y1*Z2*Z2Z2 (mag: 1) + s2.Set(y2).Mul(&z1z1).Mul(z1).Normalize() // S2 = Y2*Z1*Z1Z1 (mag: 1) + if u1.Equals(&u2) { + if s1.Equals(&s2) { + // Since x1 == x2 and y1 == y2, point doubling must be + // done, otherwise the addition would end up dividing + // by zero. + DoubleNonConst(p1, result) + return + } + + // Since x1 == x2 and y1 == -y2, the sum is the point at + // infinity per the group law. + x3.SetInt(0) + y3.SetInt(0) + z3.SetInt(0) + return + } + + // Calculate X3, Y3, and Z3 according to the intermediate elements + // breakdown above. + var h, i, j, r, rr, v FieldVal + var negU1, negS1, negX3 FieldVal + negU1.Set(&u1).Negate(1) // negU1 = -U1 (mag: 2) + h.Add2(&u2, &negU1) // H = U2-U1 (mag: 3) + i.Set(&h).MulInt(2).Square() // I = (2*H)^2 (mag: 1) + j.Mul2(&h, &i) // J = H*I (mag: 1) + negS1.Set(&s1).Negate(1) // negS1 = -S1 (mag: 2) + r.Set(&s2).Add(&negS1).MulInt(2) // r = 2*(S2-S1) (mag: 6) + rr.SquareVal(&r) // rr = r^2 (mag: 1) + v.Mul2(&u1, &i) // V = U1*I (mag: 1) + x3.Set(&v).MulInt(2).Add(&j).Negate(3) // X3 = -(J+2*V) (mag: 4) + x3.Add(&rr) // X3 = r^2+X3 (mag: 5) + negX3.Set(x3).Negate(5) // negX3 = -X3 (mag: 6) + y3.Mul2(&s1, &j).MulInt(2).Negate(2) // Y3 = -(2*S1*J) (mag: 3) + y3.Add(v.Add(&negX3).Mul(&r)) // Y3 = r*(V-X3)+Y3 (mag: 4) + z3.Add2(z1, z2).Square() // Z3 = (Z1+Z2)^2 (mag: 1) + z3.Add(z1z1.Add(&z2z2).Negate(2)) // Z3 = Z3-(Z1Z1+Z2Z2) (mag: 4) + z3.Mul(&h) // Z3 = Z3*H (mag: 1) + + // Normalize the resulting field values as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// AddNonConst adds the passed Jacobian points together and stores the result in +// the provided result param in *non-constant* time. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func AddNonConst(p1, p2, result *JacobianPoint) { + // The point at infinity is the identity according to the group law for + // elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P. + if (p1.X.IsZero() && p1.Y.IsZero()) || p1.Z.IsZero() { + result.Set(p2) + return + } + if (p2.X.IsZero() && p2.Y.IsZero()) || p2.Z.IsZero() { + result.Set(p1) + return + } + + // Faster point addition can be achieved when certain assumptions are + // met. For example, when both points have the same z value, arithmetic + // on the z values can be avoided. This section thus checks for these + // conditions and calls an appropriate add function which is accelerated + // by using those assumptions. + isZ1One := p1.Z.IsOne() + isZ2One := p2.Z.IsOne() + switch { + case isZ1One && isZ2One: + addZ1AndZ2EqualsOne(p1, p2, result) + return + case p1.Z.Equals(&p2.Z): + addZ1EqualsZ2(p1, p2, result) + return + case isZ2One: + addZ2EqualsOne(p1, p2, result) + return + } + + // None of the above assumptions are true, so fall back to generic + // point addition. + addGeneric(p1, p2, result) +} + +// doubleZ1EqualsOne performs point doubling on the passed Jacobian point when +// the point is already known to have a z value of 1 and stores the result in +// the provided result param. That is to say result = 2*p. It performs faster +// point doubling than the generic routine since less arithmetic is needed due +// to the ability to avoid multiplication by the z value. +// +// NOTE: The resulting point will be normalized. +func doubleZ1EqualsOne(p, result *JacobianPoint) { + // This function uses the assumptions that z1 is 1, thus the point + // doubling formulas reduce to: + // + // X3 = (3*X1^2)^2 - 8*X1*Y1^2 + // Y3 = (3*X1^2)*(4*X1*Y1^2 - X3) - 8*Y1^4 + // Z3 = 2*Y1 + // + // To compute the above efficiently, this implementation splits the + // equation into intermediate elements which are used to minimize the + // number of field multiplications in favor of field squarings which + // are roughly 35% faster than field multiplications with the current + // implementation at the time this was written. + // + // This uses a slightly modified version of the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl + // + // In particular it performs the calculations using the following: + // A = X1^2, B = Y1^2, C = B^2, D = 2*((X1+B)^2-A-C) + // E = 3*A, F = E^2, X3 = F-2*D, Y3 = E*(D-X3)-8*C + // Z3 = 2*Y1 + // + // This results in a cost of 1 field multiplication, 5 field squarings, + // 6 field additions, and 5 integer multiplications. + x1, y1 := &p.X, &p.Y + x3, y3, z3 := &result.X, &result.Y, &result.Z + var a, b, c, d, e, f FieldVal + z3.Set(y1).MulInt(2) // Z3 = 2*Y1 (mag: 2) + a.SquareVal(x1) // A = X1^2 (mag: 1) + b.SquareVal(y1) // B = Y1^2 (mag: 1) + c.SquareVal(&b) // C = B^2 (mag: 1) + b.Add(x1).Square() // B = (X1+B)^2 (mag: 1) + d.Set(&a).Add(&c).Negate(2) // D = -(A+C) (mag: 3) + d.Add(&b).MulInt(2) // D = 2*(B+D)(mag: 8) + e.Set(&a).MulInt(3) // E = 3*A (mag: 3) + f.SquareVal(&e) // F = E^2 (mag: 1) + x3.Set(&d).MulInt(2).Negate(16) // X3 = -(2*D) (mag: 17) + x3.Add(&f) // X3 = F+X3 (mag: 18) + f.Set(x3).Negate(18).Add(&d).Normalize() // F = D-X3 (mag: 1) + y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9) + y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10) + + // Normalize the resulting field values as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// doubleGeneric performs point doubling on the passed Jacobian point without +// any assumptions about the z value and stores the result in the provided +// result param. That is to say result = 2*p. It is the slowest of the point +// doubling routines due to requiring the most arithmetic. +// +// NOTE: The resulting point will be normalized. +func doubleGeneric(p, result *JacobianPoint) { + // Point doubling formula for Jacobian coordinates for the secp256k1 + // curve: + // + // X3 = (3*X1^2)^2 - 8*X1*Y1^2 + // Y3 = (3*X1^2)*(4*X1*Y1^2 - X3) - 8*Y1^4 + // Z3 = 2*Y1*Z1 + // + // To compute the above efficiently, this implementation splits the + // equation into intermediate elements which are used to minimize the + // number of field multiplications in favor of field squarings which + // are roughly 35% faster than field multiplications with the current + // implementation at the time this was written. + // + // This uses a slightly modified version of the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + // + // In particular it performs the calculations using the following: + // A = X1^2, B = Y1^2, C = B^2, D = 2*((X1+B)^2-A-C) + // E = 3*A, F = E^2, X3 = F-2*D, Y3 = E*(D-X3)-8*C + // Z3 = 2*Y1*Z1 + // + // This results in a cost of 1 field multiplication, 5 field squarings, + // 6 field additions, and 5 integer multiplications. + x1, y1, z1 := &p.X, &p.Y, &p.Z + x3, y3, z3 := &result.X, &result.Y, &result.Z + var a, b, c, d, e, f FieldVal + z3.Mul2(y1, z1).MulInt(2) // Z3 = 2*Y1*Z1 (mag: 2) + a.SquareVal(x1) // A = X1^2 (mag: 1) + b.SquareVal(y1) // B = Y1^2 (mag: 1) + c.SquareVal(&b) // C = B^2 (mag: 1) + b.Add(x1).Square() // B = (X1+B)^2 (mag: 1) + d.Set(&a).Add(&c).Negate(2) // D = -(A+C) (mag: 3) + d.Add(&b).MulInt(2) // D = 2*(B+D)(mag: 8) + e.Set(&a).MulInt(3) // E = 3*A (mag: 3) + f.SquareVal(&e) // F = E^2 (mag: 1) + x3.Set(&d).MulInt(2).Negate(16) // X3 = -(2*D) (mag: 17) + x3.Add(&f) // X3 = F+X3 (mag: 18) + f.Set(x3).Negate(18).Add(&d).Normalize() // F = D-X3 (mag: 1) + y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9) + y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10) + + // Normalize the resulting field values as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// DoubleNonConst doubles the passed Jacobian point and stores the result in the +// provided result parameter in *non-constant* time. +// +// NOTE: The point must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func DoubleNonConst(p, result *JacobianPoint) { + // Doubling the point at infinity is still infinity. + if p.Y.IsZero() || p.Z.IsZero() { + result.X.SetInt(0) + result.Y.SetInt(0) + result.Z.SetInt(0) + return + } + + // Slightly faster point doubling can be achieved when the z value is 1 + // by avoiding the multiplication on the z value. This section calls + // a point doubling function which is accelerated by using that + // assumption when possible. + if p.Z.IsOne() { + doubleZ1EqualsOne(p, result) + return + } + + // Fall back to generic point doubling which works with arbitrary z + // values. + doubleGeneric(p, result) +} + +// mulAdd64 multiplies the two passed base 2^64 digits together, adds the given +// value to the result, and returns the 128-bit result via a (hi, lo) tuple +// where the upper half of the bits are returned in hi and the lower half in lo. +func mulAdd64(digit1, digit2, m uint64) (hi, lo uint64) { + // Note the carry on the final add is safe to discard because the maximum + // possible value is: + // (2^64 - 1)(2^64 - 1) + (2^64 - 1) = 2^128 - 2^64 + // and: + // 2^128 - 2^64 < 2^128. + var c uint64 + hi, lo = bits.Mul64(digit1, digit2) + lo, c = bits.Add64(lo, m, 0) + hi, _ = bits.Add64(hi, 0, c) + return hi, lo +} + +// mulAdd64Carry multiplies the two passed base 2^64 digits together, adds both +// the given value and carry to the result, and returns the 128-bit result via a +// (hi, lo) tuple where the upper half of the bits are returned in hi and the +// lower half in lo. +func mulAdd64Carry(digit1, digit2, m, c uint64) (hi, lo uint64) { + // Note the carry on the high order add is safe to discard because the + // maximum possible value is: + // (2^64 - 1)(2^64 - 1) + 2*(2^64 - 1) = 2^128 - 1 + // and: + // 2^128 - 1 < 2^128. + var c2 uint64 + hi, lo = mulAdd64(digit1, digit2, m) + lo, c2 = bits.Add64(lo, c, 0) + hi, _ = bits.Add64(hi, 0, c2) + return hi, lo +} + +// mul512Rsh320Round computes the full 512-bit product of the two given scalars, +// right shifts the result by 320 bits, rounds to the nearest integer, and +// returns the result in constant time. +// +// Note that despite the inputs and output being mod n scalars, the 512-bit +// product is NOT reduced mod N prior to the right shift. This is intentional +// because it is used for replacing division with multiplication and thus the +// intermediate results must be done via a field extension to a larger field. +func mul512Rsh320Round(n1, n2 *ModNScalar) ModNScalar { + // Convert n1 and n2 to base 2^64 digits. + n1Digit0 := uint64(n1.n[0]) | uint64(n1.n[1])<<32 + n1Digit1 := uint64(n1.n[2]) | uint64(n1.n[3])<<32 + n1Digit2 := uint64(n1.n[4]) | uint64(n1.n[5])<<32 + n1Digit3 := uint64(n1.n[6]) | uint64(n1.n[7])<<32 + n2Digit0 := uint64(n2.n[0]) | uint64(n2.n[1])<<32 + n2Digit1 := uint64(n2.n[2]) | uint64(n2.n[3])<<32 + n2Digit2 := uint64(n2.n[4]) | uint64(n2.n[5])<<32 + n2Digit3 := uint64(n2.n[6]) | uint64(n2.n[7])<<32 + + // Compute the full 512-bit product n1*n2. + var r0, r1, r2, r3, r4, r5, r6, r7, c uint64 + + // Terms resulting from the product of the first digit of the second number + // by all digits of the first number. + // + // Note that r0 is ignored because it is not needed to compute the higher + // terms and it is shifted out below anyway. + c, _ = bits.Mul64(n2Digit0, n1Digit0) + c, r1 = mulAdd64(n2Digit0, n1Digit1, c) + c, r2 = mulAdd64(n2Digit0, n1Digit2, c) + r4, r3 = mulAdd64(n2Digit0, n1Digit3, c) + + // Terms resulting from the product of the second digit of the second number + // by all digits of the first number. + // + // Note that r1 is ignored because it is no longer needed to compute the + // higher terms and it is shifted out below anyway. + c, _ = mulAdd64(n2Digit1, n1Digit0, r1) + c, r2 = mulAdd64Carry(n2Digit1, n1Digit1, r2, c) + c, r3 = mulAdd64Carry(n2Digit1, n1Digit2, r3, c) + r5, r4 = mulAdd64Carry(n2Digit1, n1Digit3, r4, c) + + // Terms resulting from the product of the third digit of the second number + // by all digits of the first number. + // + // Note that r2 is ignored because it is no longer needed to compute the + // higher terms and it is shifted out below anyway. + c, _ = mulAdd64(n2Digit2, n1Digit0, r2) + c, r3 = mulAdd64Carry(n2Digit2, n1Digit1, r3, c) + c, r4 = mulAdd64Carry(n2Digit2, n1Digit2, r4, c) + r6, r5 = mulAdd64Carry(n2Digit2, n1Digit3, r5, c) + + // Terms resulting from the product of the fourth digit of the second number + // by all digits of the first number. + // + // Note that r3 is ignored because it is no longer needed to compute the + // higher terms and it is shifted out below anyway. + c, _ = mulAdd64(n2Digit3, n1Digit0, r3) + c, r4 = mulAdd64Carry(n2Digit3, n1Digit1, r4, c) + c, r5 = mulAdd64Carry(n2Digit3, n1Digit2, r5, c) + r7, r6 = mulAdd64Carry(n2Digit3, n1Digit3, r6, c) + + // At this point the upper 256 bits of the full 512-bit product n1*n2 are in + // r4..r7 (recall the low order results were discarded as noted above). + // + // Right shift the result 320 bits. Note that the MSB of r4 determines + // whether or not to round because it is the final bit that is shifted out. + // + // Also, notice that r3..r7 would also ordinarily be set to 0 as well for + // the full shift, but that is skipped since they are no longer used as + // their values are known to be zero. + roundBit := r4 >> 63 + r2, r1, r0 = r7, r6, r5 + + // Conditionally add 1 depending on the round bit in constant time. + r0, c = bits.Add64(r0, roundBit, 0) + r1, c = bits.Add64(r1, 0, c) + r2, r3 = bits.Add64(r2, 0, c) + + // Finally, convert the result to a mod n scalar. + // + // No modular reduction is needed because the result is guaranteed to be + // less than the group order given the group order is > 2^255 and the + // maximum possible value of the result is 2^192. + var result ModNScalar + result.n[0] = uint32(r0) + result.n[1] = uint32(r0 >> 32) + result.n[2] = uint32(r1) + result.n[3] = uint32(r1 >> 32) + result.n[4] = uint32(r2) + result.n[5] = uint32(r2 >> 32) + result.n[6] = uint32(r3) + result.n[7] = uint32(r3 >> 32) + return result +} + +// splitK returns two scalars (k1 and k2) that are a balanced length-two +// representation of the provided scalar such that k ≡ k1 + k2*λ (mod N), where +// N is the secp256k1 group order. +func splitK(k *ModNScalar) (ModNScalar, ModNScalar) { + // The ultimate goal is to decompose k into two scalars that are around + // half the bit length of k such that the following equation is satisfied: + // + // k1 + k2*λ ≡ k (mod n) + // + // The strategy used here is based on algorithm 3.74 from [GECC] with a few + // modifications to make use of the more efficient mod n scalar type, avoid + // some costly long divisions, and minimize the number of calculations. + // + // Start by defining a function that takes a vector v = ∈ ℤ⨯ℤ: + // + // f(v) = a + bλ (mod n) + // + // Then, find two vectors, v1 = , and v2 = in ℤ⨯ℤ such that: + // 1) v1 and v2 are linearly independent + // 2) f(v1) = f(v2) = 0 + // 3) v1 and v2 have small Euclidean norm + // + // The vectors that satisfy these properties are found via the Euclidean + // algorithm and are precomputed since both n and λ are fixed values for the + // secp256k1 curve. See genprecomps.go for derivation details. + // + // Next, consider k as a vector in ℚ⨯ℚ and by linear algebra write: + // + // = g1*v1 + g2*v2, where g1, g2 ∈ ℚ + // + // Note that, per above, the components of vector v1 are a1 and b1 while the + // components of vector v2 are a2 and b2. Given the vectors v1 and v2 were + // generated such that a1*b2 - a2*b1 = n, solving the equation for g1 and g2 + // yields: + // + // g1 = b2*k / n + // g2 = -b1*k / n + // + // Observe: + // = g1*v1 + g2*v2 + // = (b2*k/n)* + (-b1*k/n)* | substitute + // = + <-a2*b1*k/n, -b2*b1*k/n> | scalar mul + // = | vector add + // = <[a1*b2*k - a2*b1*k]/n, 0> | simplify + // = | factor out k + // = | substitute + // = | simplify + // + // Now, consider an integer-valued vector v: + // + // v = c1*v1 + c2*v2, where c1, c2 ∈ ℤ (mod n) + // + // Since vectors v1 and v2 are linearly independent and were generated such + // that f(v1) = f(v2) = 0, all possible scalars c1 and c2 also produce a + // vector v such that f(v) = 0. + // + // In other words, c1 and c2 can be any integers and the resulting + // decomposition will still satisfy the required equation. However, since + // the goal is to produce a balanced decomposition that provides a + // performance advantage by minimizing max(k1, k2), c1 and c2 need to be + // integers close to g1 and g2, respectively, so the resulting vector v is + // an integer-valued vector that is close to . + // + // Finally, consider the vector u: + // + // u = - v + // + // It follows that f(u) = k and thus the two components of vector u satisfy + // the required equation: + // + // k1 + k2*λ ≡ k (mod n) + // + // Choosing c1 and c2: + // ------------------- + // + // As mentioned above, c1 and c2 need to be integers close to g1 and g2, + // respectively. The algorithm in [GECC] chooses the following values: + // + // c1 = round(g1) = round(b2*k / n) + // c2 = round(g2) = round(-b1*k / n) + // + // However, as section 3.4.2 of [STWS] notes, the aforementioned approach + // requires costly long divisions that can be avoided by precomputing + // rounded estimates as follows: + // + // t = bitlen(n) + 1 + // z1 = round(2^t * b2 / n) + // z2 = round(2^t * -b1 / n) + // + // Then, use those precomputed estimates to perform a multiplication by k + // along with a floored division by 2^t, which is a simple right shift by t: + // + // c1 = floor(k * z1 / 2^t) = (k * z1) >> t + // c2 = floor(k * z2 / 2^t) = (k * z2) >> t + // + // Finally, round up if last bit discarded in the right shift by t is set by + // adding 1. + // + // As a further optimization, rather than setting t = bitlen(n) + 1 = 257 as + // stated by [STWS], this implementation uses a higher precision estimate of + // t = bitlen(n) + 64 = 320 because it allows simplification of the shifts + // in the internal calculations that are done via uint64s and also allows + // the use of floor in the precomputations. + // + // Thus, the calculations this implementation uses are: + // + // z1 = floor(b2<<320 / n) | precomputed + // z2 = floor((-b1)<<320) / n) | precomputed + // c1 = ((k * z1) >> 320) + (((k * z1) >> 319) & 1) + // c2 = ((k * z2) >> 320) + (((k * z2) >> 319) & 1) + // + // Putting it all together: + // ------------------------ + // + // Calculate the following vectors using the values discussed above: + // + // v = c1*v1 + c2*v2 + // u = - v + // + // The two components of the resulting vector v are: + // va = c1*a1 + c2*a2 + // vb = c1*b1 + c2*b2 + // + // Thus, the two components of the resulting vector u are: + // k1 = k - va + // k2 = 0 - vb = -vb + // + // As some final optimizations: + // + // 1) Note that k1 + k2*λ ≡ k (mod n) means that k1 ≡ k - k2*λ (mod n). + // Therefore, the computation of va can be avoided to save two + // field multiplications and a field addition. + // + // 2) Since k1 = k - k2*λ = k + k2*(-λ), an additional field negation is + // saved by storing and using the negative version of λ. + // + // 3) Since k2 = -vb = -(c1*b1 + c2*b2) = c1*(-b1) + c2*(-b2), one more + // field negation is saved by storing and using the negative versions of + // b1 and b2. + // + // k2 = c1*(-b1) + c2*(-b2) + // k1 = k + k2*(-λ) + var k1, k2 ModNScalar + c1 := mul512Rsh320Round(k, endoZ1) + c2 := mul512Rsh320Round(k, endoZ2) + k2.Add2(c1.Mul(endoNegB1), c2.Mul(endoNegB2)) + k1.Mul2(&k2, endoNegLambda).Add(k) + return k1, k2 +} + +// nafScalar represents a positive integer up to a maximum value of 2^256 - 1 +// encoded in non-adjacent form. +// +// NAF is a signed-digit representation where each digit can be +1, 0, or -1. +// +// In order to efficiently encode that information, this type uses two arrays, a +// "positive" array where set bits represent the +1 signed digits and a +// "negative" array where set bits represent the -1 signed digits. 0 is +// represented by neither array having a bit set in that position. +// +// The Pos and Neg methods return the aforementioned positive and negative +// arrays, respectively. +type nafScalar struct { + // pos houses the positive portion of the representation. An additional + // byte is required for the positive portion because the NAF encoding can be + // up to 1 bit longer than the normal binary encoding of the value. + // + // neg houses the negative portion of the representation. Even though the + // additional byte is not required for the negative portion, since it can + // never exceed the length of the normal binary encoding of the value, + // keeping the same length for positive and negative portions simplifies + // working with the representation and allows extra conditional branches to + // be avoided. + // + // start and end specify the starting and ending index to use within the pos + // and neg arrays, respectively. This allows fixed size arrays to be used + // versus needing to dynamically allocate space on the heap. + // + // NOTE: The fields are defined in the order that they are to minimize the + // padding on 32-bit and 64-bit platforms. + pos [33]byte + start, end uint8 + neg [33]byte +} + +// Pos returns the bytes of the encoded value with bits set in the positions +// that represent a signed digit of +1. +func (s *nafScalar) Pos() []byte { + return s.pos[s.start:s.end] +} + +// Neg returns the bytes of the encoded value with bits set in the positions +// that represent a signed digit of -1. +func (s *nafScalar) Neg() []byte { + return s.neg[s.start:s.end] +} + +// naf takes a positive integer up to a maximum value of 2^256 - 1 and returns +// its non-adjacent form (NAF), which is a unique signed-digit representation +// such that no two consecutive digits are nonzero. See the documentation for +// the returned type for details on how the representation is encoded +// efficiently and how to interpret it +// +// NAF is useful in that it has the fewest nonzero digits of any signed digit +// representation, only 1/3rd of its digits are nonzero on average, and at least +// half of the digits will be 0. +// +// The aforementioned properties are particularly beneficial for optimizing +// elliptic curve point multiplication because they effectively minimize the +// number of required point additions in exchange for needing to perform a mix +// of fewer point additions and subtractions and possibly one additional point +// doubling. This is an excellent tradeoff because subtraction of points has +// the same computational complexity as addition of points and point doubling is +// faster than both. +func naf(k []byte) nafScalar { + // Strip leading zero bytes. + for len(k) > 0 && k[0] == 0x00 { + k = k[1:] + } + + // The non-adjacent form (NAF) of a positive integer k is an expression + // k = ∑_(i=0, l-1) k_i * 2^i where k_i ∈ {0,±1}, k_(l-1) != 0, and no two + // consecutive digits k_i are nonzero. + // + // The traditional method of computing the NAF of a positive integer is + // given by algorithm 3.30 in [GECC]. It consists of repeatedly dividing k + // by 2 and choosing the remainder so that the quotient (k−r)/2 is even + // which ensures the next NAF digit is 0. This requires log_2(k) steps. + // + // However, in [BRID], Prodinger notes that a closed form expression for the + // NAF representation is the bitwise difference 3k/2 - k/2. This is more + // efficient as it can be computed in O(1) versus the O(log(n)) of the + // traditional approach. + // + // The following code makes use of that formula to compute the NAF more + // efficiently. + // + // To understand the logic here, observe that the only way the NAF has a + // nonzero digit at a given bit is when either 3k/2 or k/2 has a bit set in + // that position, but not both. In other words, the result of a bitwise + // xor. This can be seen simply by considering that when the bits are the + // same, the subtraction is either 0-0 or 1-1, both of which are 0. + // + // Further, observe that the "+1" digits in the result are contributed by + // 3k/2 while the "-1" digits are from k/2. So, they can be determined by + // taking the bitwise and of each respective value with the result of the + // xor which identifies which bits are nonzero. + // + // Using that information, this loops backwards from the least significant + // byte to the most significant byte while performing the aforementioned + // calculations by propagating the potential carry and high order bit from + // the next word during the right shift. + kLen := len(k) + var result nafScalar + var carry uint8 + for byteNum := kLen - 1; byteNum >= 0; byteNum-- { + // Calculate k/2. Notice the carry from the previous word is added and + // the low order bit from the next word is shifted in accordingly. + kc := uint16(k[byteNum]) + uint16(carry) + var nextWord uint8 + if byteNum > 0 { + nextWord = k[byteNum-1] + } + halfK := kc>>1 | uint16(nextWord<<7) + + // Calculate 3k/2 and determine the non-zero digits in the result. + threeHalfK := kc + halfK + nonZeroResultDigits := threeHalfK ^ halfK + + // Determine the signed digits {0, ±1}. + result.pos[byteNum+1] = uint8(threeHalfK & nonZeroResultDigits) + result.neg[byteNum+1] = uint8(halfK & nonZeroResultDigits) + + // Propagate the potential carry from the 3k/2 calculation. + carry = uint8(threeHalfK >> 8) + } + result.pos[0] = carry + + // Set the starting and ending positions within the fixed size arrays to + // identify the bytes that are actually used. This is important since the + // encoding is big endian and thus trailing zero bytes changes its value. + result.start = 1 - carry + result.end = uint8(kLen + 1) + return result +} + +// ScalarMultNonConst multiplies k*P where k is a scalar modulo the curve order +// and P is a point in Jacobian projective coordinates and stores the result in +// the provided Jacobian point. +// +// NOTE: The point must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint) { + // ------------------------------------------------------------------------- + // This makes use of the following efficiently-computable endomorphism to + // accelerate the computation: + // + // φ(P) ⟼ λ*P = (β*P.x mod p, P.y) + // + // In other words, there is a special scalar λ that every point on the + // elliptic curve can be multiplied by that will result in the same point as + // performing a single field multiplication of the point's X coordinate by + // the special value β. + // + // This is useful because scalar point multiplication is significantly more + // expensive than a single field multiplication given the former involves a + // series of point doublings and additions which themselves consist of a + // combination of several field multiplications, squarings, and additions. + // + // So, the idea behind making use of the endomorphism is thus to decompose + // the scalar into two scalars that are each about half the bit length of + // the original scalar such that: + // + // k ≡ k1 + k2*λ (mod n) + // + // This in turn allows the scalar point multiplication to be performed as a + // sum of two smaller half-length multiplications as follows: + // + // k*P = (k1 + k2*λ)*P + // = k1*P + k2*λ*P + // = k1*P + k2*φ(P) + // + // Thus, a speedup is achieved so long as it's faster to decompose the + // scalar, compute φ(P), and perform a simultaneous multiply of the + // half-length point multiplications than it is to compute a full width + // point multiplication. + // + // In practice, benchmarks show the current implementation provides a + // speedup of around 30-35% versus not using the endomorphism. + // + // See section 3.5 in [GECC] for a more rigorous treatment. + // ------------------------------------------------------------------------- + + // Per above, the main equation here to remember is: + // k*P = k1*P + k2*φ(P) + // + // p1 below is P in the equation while p2 is φ(P) in the equation. + // + // NOTE: φ(x,y) = (β*x,y). The Jacobian z coordinates are the same, so this + // math goes through. + // + // Also, calculate -p1 and -p2 for use in the NAF optimization. + p1, p1Neg := new(JacobianPoint), new(JacobianPoint) + p1.Set(point) + p1Neg.Set(p1) + p1Neg.Y.Negate(1).Normalize() + p2, p2Neg := new(JacobianPoint), new(JacobianPoint) + p2.Set(p1) + p2.X.Mul(endoBeta).Normalize() + p2Neg.Set(p2) + p2Neg.Y.Negate(1).Normalize() + + // Decompose k into k1 and k2 such that k = k1 + k2*λ (mod n) where k1 and + // k2 are around half the bit length of k in order to halve the number of EC + // operations. + // + // Notice that this also flips the sign of the scalars and points as needed + // to minimize the bit lengths of the scalars k1 and k2. + // + // This is done because the scalars are operating modulo the group order + // which means that when they would otherwise be a small negative magnitude + // they will instead be a large positive magnitude. Since the goal is for + // the scalars to have a small magnitude to achieve a performance boost, use + // their negation when they are greater than the half order of the group and + // flip the positive and negative values of the corresponding point that + // will be multiplied by to compensate. + // + // In other words, transform the calc when k1 is over the half order to: + // k1*P = -k1*-P + // + // Similarly, transform the calc when k2 is over the half order to: + // k2*φ(P) = -k2*-φ(P) + k1, k2 := splitK(k) + if k1.IsOverHalfOrder() { + k1.Negate() + p1, p1Neg = p1Neg, p1 + } + if k2.IsOverHalfOrder() { + k2.Negate() + p2, p2Neg = p2Neg, p2 + } + + // Convert k1 and k2 into their NAF representations since NAF has a lot more + // zeros overall on average which minimizes the number of required point + // additions in exchange for a mix of fewer point additions and subtractions + // at the cost of one additional point doubling. + // + // This is an excellent tradeoff because subtraction of points has the same + // computational complexity as addition of points and point doubling is + // faster than both. + // + // Concretely, on average, 1/2 of all bits will be non-zero with the normal + // binary representation whereas only 1/3rd of the bits will be non-zero + // with NAF. + // + // The Pos version of the bytes contain the +1s and the Neg versions contain + // the -1s. + k1Bytes, k2Bytes := k1.Bytes(), k2.Bytes() + k1NAF, k2NAF := naf(k1Bytes[:]), naf(k2Bytes[:]) + k1PosNAF, k1NegNAF := k1NAF.Pos(), k1NAF.Neg() + k2PosNAF, k2NegNAF := k2NAF.Pos(), k2NAF.Neg() + k1Len, k2Len := len(k1PosNAF), len(k2PosNAF) + + // Add left-to-right using the NAF optimization. See algorithm 3.77 from + // [GECC]. + // + // Point Q = ∞ (point at infinity). + var q JacobianPoint + m := k1Len + if m < k2Len { + m = k2Len + } + for i := 0; i < m; i++ { + // Since k1 and k2 are potentially different lengths and the calculation + // is being done left to right, pad the front of the shorter one with + // 0s. + var k1BytePos, k1ByteNeg, k2BytePos, k2ByteNeg byte + if i >= m-k1Len { + k1BytePos, k1ByteNeg = k1PosNAF[i-(m-k1Len)], k1NegNAF[i-(m-k1Len)] + } + if i >= m-k2Len { + k2BytePos, k2ByteNeg = k2PosNAF[i-(m-k2Len)], k2NegNAF[i-(m-k2Len)] + } + + for mask := uint8(1 << 7); mask > 0; mask >>= 1 { + // Q = 2 * Q + DoubleNonConst(&q, &q) + + // Add or subtract the first point based on the signed digit of the + // NAF representation of k1 at this bit position. + // + // +1: Q = Q + p1 + // -1: Q = Q - p1 + // 0: Q = Q (no change) + if k1BytePos&mask == mask { + AddNonConst(&q, p1, &q) + } else if k1ByteNeg&mask == mask { + AddNonConst(&q, p1Neg, &q) + } + + // Add or subtract the second point based on the signed digit of the + // NAF representation of k2 at this bit position. + // + // +1: Q = Q + p2 + // -1: Q = Q - p2 + // 0: Q = Q (no change) + if k2BytePos&mask == mask { + AddNonConst(&q, p2, &q) + } else if k2ByteNeg&mask == mask { + AddNonConst(&q, p2Neg, &q) + } + } + } + + result.Set(&q) +} + +// ScalarBaseMultNonConst multiplies k*G where k is a scalar modulo the curve +// order and G is the base point of the group and stores the result in the +// provided Jacobian point. +// +// NOTE: The resulting point will be normalized. +func ScalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) { + bytePoints := s256BytePoints() + + // Start with the point at infinity. + result.X.Zero() + result.Y.Zero() + result.Z.Zero() + + // bytePoints has all 256 byte points for each 8-bit window. The strategy + // is to add up the byte points. This is best understood by expressing k in + // base-256 which it already sort of is. Each "digit" in the 8-bit window + // can be looked up using bytePoints and added together. + kb := k.Bytes() + for i := 0; i < len(kb); i++ { + pt := &bytePoints[i][kb[i]] + AddNonConst(result, pt, result) + } +} + +// isOnCurve returns whether or not the affine point (x,y) is on the curve. +func isOnCurve(fx, fy *FieldVal) bool { + // Elliptic curve equation for secp256k1 is: y^2 = x^3 + 7 + y2 := new(FieldVal).SquareVal(fy).Normalize() + result := new(FieldVal).SquareVal(fx).Mul(fx).AddInt(7).Normalize() + return y2.Equals(result) +} + +// DecompressY attempts to calculate the Y coordinate for the given X coordinate +// such that the result pair is a point on the secp256k1 curve. It adjusts Y +// based on the desired oddness and returns whether or not it was successful +// since not all X coordinates are valid. +// +// The magnitude of the provided X coordinate field val must be a max of 8 for a +// correct result. The resulting Y field val will have a max magnitude of 2. +func DecompressY(x *FieldVal, odd bool, resultY *FieldVal) bool { + // The curve equation for secp256k1 is: y^2 = x^3 + 7. Thus + // y = +-sqrt(x^3 + 7). + // + // The x coordinate must be invalid if there is no square root for the + // calculated rhs because it means the X coordinate is not for a point on + // the curve. + x3PlusB := new(FieldVal).SquareVal(x).Mul(x).AddInt(7) + if hasSqrt := resultY.SquareRootVal(x3PlusB); !hasSqrt { + return false + } + if resultY.Normalize().IsOdd() != odd { + resultY.Negate(1) + } + return true +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go new file mode 100644 index 000000000..ac01e2343 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go @@ -0,0 +1,59 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2022 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +/* +Package secp256k1 implements optimized secp256k1 elliptic curve operations in +pure Go. + +This package provides an optimized pure Go implementation of elliptic curve +cryptography operations over the secp256k1 curve as well as data structures and +functions for working with public and private secp256k1 keys. See +https://www.secg.org/sec2-v2.pdf for details on the standard. + +In addition, sub packages are provided to produce, verify, parse, and serialize +ECDSA signatures and EC-Schnorr-DCRv0 (a custom Schnorr-based signature scheme +specific to Decred) signatures. See the README.md files in the relevant sub +packages for more details about those aspects. + +An overview of the features provided by this package are as follows: + + - Private key generation, serialization, and parsing + - Public key generation, serialization and parsing per ANSI X9.62-1998 + - Parses uncompressed, compressed, and hybrid public keys + - Serializes uncompressed and compressed public keys + - Specialized types for performing optimized and constant time field operations + - FieldVal type for working modulo the secp256k1 field prime + - ModNScalar type for working modulo the secp256k1 group order + - Elliptic curve operations in Jacobian projective coordinates + - Point addition + - Point doubling + - Scalar multiplication with an arbitrary point + - Scalar multiplication with the base point (group generator) + - Point decompression from a given x coordinate + - Nonce generation via RFC6979 with support for extra data and version + information that can be used to prevent nonce reuse between signing + algorithms + +It also provides an implementation of the Go standard library crypto/elliptic +Curve interface via the S256 function so that it may be used with other packages +in the standard library such as crypto/tls, crypto/x509, and crypto/ecdsa. +However, in the case of ECDSA, it is highly recommended to use the ecdsa sub +package of this package instead since it is optimized specifically for secp256k1 +and is significantly faster as a result. + +Although this package was primarily written for dcrd, it has intentionally been +designed so it can be used as a standalone package for any projects needing to +use optimized secp256k1 elliptic curve cryptography. + +Finally, a comprehensive suite of tests is provided to provide a high level of +quality assurance. + +# Use of secp256k1 in Decred + +At the time of this writing, the primary public key cryptography in widespread +use on the Decred network used to secure coins is based on elliptic curves +defined by the secp256k1 domain parameters. +*/ +package secp256k1 diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go new file mode 100644 index 000000000..96869a3cd --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go @@ -0,0 +1,21 @@ +// Copyright (c) 2015 The btcsuite developers +// Copyright (c) 2015-2023 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// GenerateSharedSecret generates a shared secret based on a private key and a +// public key using Diffie-Hellman key exchange (ECDH) (RFC 5903). +// RFC5903 Section 9 states we should only return x. +// +// It is recommended to securely hash the result before using as a cryptographic +// key. +func GenerateSharedSecret(privkey *PrivateKey, pubkey *PublicKey) []byte { + var point, result JacobianPoint + pubkey.AsJacobian(&point) + ScalarMultNonConst(&privkey.Key, &point, &result) + result.ToAffine() + xBytes := result.X.Bytes() + return xBytes[:] +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go new file mode 100644 index 000000000..42022646b --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go @@ -0,0 +1,255 @@ +// Copyright 2020-2022 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// References: +// [SECG]: Recommended Elliptic Curve Domain Parameters +// https://www.secg.org/sec2-v2.pdf +// +// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone) + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "math/big" +) + +// CurveParams contains the parameters for the secp256k1 curve. +type CurveParams struct { + // P is the prime used in the secp256k1 field. + P *big.Int + + // N is the order of the secp256k1 curve group generated by the base point. + N *big.Int + + // Gx and Gy are the x and y coordinate of the base point, respectively. + Gx, Gy *big.Int + + // BitSize is the size of the underlying secp256k1 field in bits. + BitSize int + + // H is the cofactor of the secp256k1 curve. + H int + + // ByteSize is simply the bit size / 8 and is provided for convenience + // since it is calculated repeatedly. + ByteSize int +} + +// Curve parameters taken from [SECG] section 2.4.1. +var curveParams = CurveParams{ + P: fromHex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"), + N: fromHex("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"), + Gx: fromHex("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"), + Gy: fromHex("483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"), + BitSize: 256, + H: 1, + ByteSize: 256 / 8, +} + +// Params returns the secp256k1 curve parameters for convenience. +func Params() *CurveParams { + return &curveParams +} + +// KoblitzCurve provides an implementation for secp256k1 that fits the ECC Curve +// interface from crypto/elliptic. +type KoblitzCurve struct { + *elliptic.CurveParams +} + +// bigAffineToJacobian takes an affine point (x, y) as big integers and converts +// it to Jacobian point with Z=1. +func bigAffineToJacobian(x, y *big.Int, result *JacobianPoint) { + result.X.SetByteSlice(x.Bytes()) + result.Y.SetByteSlice(y.Bytes()) + result.Z.SetInt(1) +} + +// jacobianToBigAffine takes a Jacobian point (x, y, z) as field values and +// converts it to an affine point as big integers. +func jacobianToBigAffine(point *JacobianPoint) (*big.Int, *big.Int) { + point.ToAffine() + + // Convert the field values for the now affine point to big.Ints. + x3, y3 := new(big.Int), new(big.Int) + x3.SetBytes(point.X.Bytes()[:]) + y3.SetBytes(point.Y.Bytes()[:]) + return x3, y3 +} + +// Params returns the parameters for the curve. +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) Params() *elliptic.CurveParams { + return curve.CurveParams +} + +// IsOnCurve returns whether or not the affine point (x,y) is on the curve. +// +// This is part of the elliptic.Curve interface implementation. This function +// differs from the crypto/elliptic algorithm since a = 0 not -3. +func (curve *KoblitzCurve) IsOnCurve(x, y *big.Int) bool { + // Convert big ints to a Jacobian point for faster arithmetic. + var point JacobianPoint + bigAffineToJacobian(x, y, &point) + return isOnCurve(&point.X, &point.Y) +} + +// Add returns the sum of (x1,y1) and (x2,y2). +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { + // The point at infinity is the identity according to the group law for + // elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P. + if x1.Sign() == 0 && y1.Sign() == 0 { + return x2, y2 + } + if x2.Sign() == 0 && y2.Sign() == 0 { + return x1, y1 + } + + // Convert the affine coordinates from big integers to Jacobian points, + // do the point addition in Jacobian projective space, and convert the + // Jacobian point back to affine big.Ints. + var p1, p2, result JacobianPoint + bigAffineToJacobian(x1, y1, &p1) + bigAffineToJacobian(x2, y2, &p2) + AddNonConst(&p1, &p2, &result) + return jacobianToBigAffine(&result) +} + +// Double returns 2*(x1,y1). +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { + if y1.Sign() == 0 { + return new(big.Int), new(big.Int) + } + + // Convert the affine coordinates from big integers to Jacobian points, + // do the point doubling in Jacobian projective space, and convert the + // Jacobian point back to affine big.Ints. + var point, result JacobianPoint + bigAffineToJacobian(x1, y1, &point) + DoubleNonConst(&point, &result) + return jacobianToBigAffine(&result) +} + +// moduloReduce reduces k from more than 32 bytes to 32 bytes and under. This +// is done by doing a simple modulo curve.N. We can do this since G^N = 1 and +// thus any other valid point on the elliptic curve has the same order. +func moduloReduce(k []byte) []byte { + // Since the order of G is curve.N, we can use a much smaller number by + // doing modulo curve.N + if len(k) > curveParams.ByteSize { + tmpK := new(big.Int).SetBytes(k) + tmpK.Mod(tmpK, curveParams.N) + return tmpK.Bytes() + } + + return k +} + +// ScalarMult returns k*(Bx, By) where k is a big endian integer. +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { + // Convert the affine coordinates from big integers to Jacobian points, + // do the multiplication in Jacobian projective space, and convert the + // Jacobian point back to affine big.Ints. + var kModN ModNScalar + kModN.SetByteSlice(moduloReduce(k)) + var point, result JacobianPoint + bigAffineToJacobian(Bx, By, &point) + ScalarMultNonConst(&kModN, &point, &result) + return jacobianToBigAffine(&result) +} + +// ScalarBaseMult returns k*G where G is the base point of the group and k is a +// big endian integer. +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { + // Perform the multiplication and convert the Jacobian point back to affine + // big.Ints. + var kModN ModNScalar + kModN.SetByteSlice(moduloReduce(k)) + var result JacobianPoint + ScalarBaseMultNonConst(&kModN, &result) + return jacobianToBigAffine(&result) +} + +// X returns the x coordinate of the public key. +func (p *PublicKey) X() *big.Int { + return new(big.Int).SetBytes(p.x.Bytes()[:]) +} + +// Y returns the y coordinate of the public key. +func (p *PublicKey) Y() *big.Int { + return new(big.Int).SetBytes(p.y.Bytes()[:]) +} + +// ToECDSA returns the public key as a *ecdsa.PublicKey. +func (p *PublicKey) ToECDSA() *ecdsa.PublicKey { + return &ecdsa.PublicKey{ + Curve: S256(), + X: p.X(), + Y: p.Y(), + } +} + +// ToECDSA returns the private key as a *ecdsa.PrivateKey. +func (p *PrivateKey) ToECDSA() *ecdsa.PrivateKey { + var privKeyBytes [PrivKeyBytesLen]byte + p.Key.PutBytes(&privKeyBytes) + var result JacobianPoint + ScalarBaseMultNonConst(&p.Key, &result) + x, y := jacobianToBigAffine(&result) + newPrivKey := &ecdsa.PrivateKey{ + PublicKey: ecdsa.PublicKey{ + Curve: S256(), + X: x, + Y: y, + }, + D: new(big.Int).SetBytes(privKeyBytes[:]), + } + zeroArray32(&privKeyBytes) + return newPrivKey +} + +// fromHex converts the passed hex string into a big integer pointer and will +// panic is there is an error. This is only provided for the hard-coded +// constants so errors in the source code can bet detected. It will only (and +// must only) be called for initialization purposes. +func fromHex(s string) *big.Int { + if s == "" { + return big.NewInt(0) + } + r, ok := new(big.Int).SetString(s, 16) + if !ok { + panic("invalid hex in source file: " + s) + } + return r +} + +// secp256k1 is a global instance of the KoblitzCurve implementation which in +// turn embeds and implements elliptic.CurveParams. +var secp256k1 = &KoblitzCurve{ + CurveParams: &elliptic.CurveParams{ + P: curveParams.P, + N: curveParams.N, + B: fromHex("0000000000000000000000000000000000000000000000000000000000000007"), + Gx: curveParams.Gx, + Gy: curveParams.Gy, + BitSize: curveParams.BitSize, + Name: "secp256k1", + }, +} + +// S256 returns an elliptic.Curve which implements secp256k1. +func S256() *KoblitzCurve { + return secp256k1 +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go new file mode 100644 index 000000000..ac8c45127 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go @@ -0,0 +1,67 @@ +// Copyright (c) 2020 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// ErrorKind identifies a kind of error. It has full support for errors.Is and +// errors.As, so the caller can directly check against an error kind when +// determining the reason for an error. +type ErrorKind string + +// These constants are used to identify a specific RuleError. +const ( + // ErrPubKeyInvalidLen indicates that the length of a serialized public + // key is not one of the allowed lengths. + ErrPubKeyInvalidLen = ErrorKind("ErrPubKeyInvalidLen") + + // ErrPubKeyInvalidFormat indicates an attempt was made to parse a public + // key that does not specify one of the supported formats. + ErrPubKeyInvalidFormat = ErrorKind("ErrPubKeyInvalidFormat") + + // ErrPubKeyXTooBig indicates that the x coordinate for a public key + // is greater than or equal to the prime of the field underlying the group. + ErrPubKeyXTooBig = ErrorKind("ErrPubKeyXTooBig") + + // ErrPubKeyYTooBig indicates that the y coordinate for a public key is + // greater than or equal to the prime of the field underlying the group. + ErrPubKeyYTooBig = ErrorKind("ErrPubKeyYTooBig") + + // ErrPubKeyNotOnCurve indicates that a public key is not a point on the + // secp256k1 curve. + ErrPubKeyNotOnCurve = ErrorKind("ErrPubKeyNotOnCurve") + + // ErrPubKeyMismatchedOddness indicates that a hybrid public key specified + // an oddness of the y coordinate that does not match the actual oddness of + // the provided y coordinate. + ErrPubKeyMismatchedOddness = ErrorKind("ErrPubKeyMismatchedOddness") +) + +// Error satisfies the error interface and prints human-readable errors. +func (e ErrorKind) Error() string { + return string(e) +} + +// Error identifies an error related to public key cryptography using a +// sec256k1 curve. It has full support for errors.Is and errors.As, so the +// caller can ascertain the specific reason for the error by checking +// the underlying error. +type Error struct { + Err error + Description string +} + +// Error satisfies the error interface and prints human-readable errors. +func (e Error) Error() string { + return e.Description +} + +// Unwrap returns the underlying wrapped error. +func (e Error) Unwrap() error { + return e.Err +} + +// makeError creates an Error given a set of arguments. +func makeError(kind ErrorKind, desc string) Error { + return Error{Err: kind, Description: desc} +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go new file mode 100644 index 000000000..8d9ac74d5 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go @@ -0,0 +1,1681 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2022 The Decred developers +// Copyright (c) 2013-2022 Dave Collins +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// References: +// [HAC]: Handbook of Applied Cryptography Menezes, van Oorschot, Vanstone. +// http://cacr.uwaterloo.ca/hac/ + +// All elliptic curve operations for secp256k1 are done in a finite field +// characterized by a 256-bit prime. Given this precision is larger than the +// biggest available native type, obviously some form of bignum math is needed. +// This package implements specialized fixed-precision field arithmetic rather +// than relying on an arbitrary-precision arithmetic package such as math/big +// for dealing with the field math since the size is known. As a result, rather +// large performance gains are achieved by taking advantage of many +// optimizations not available to arbitrary-precision arithmetic and generic +// modular arithmetic algorithms. +// +// There are various ways to internally represent each finite field element. +// For example, the most obvious representation would be to use an array of 4 +// uint64s (64 bits * 4 = 256 bits). However, that representation suffers from +// a couple of issues. First, there is no native Go type large enough to handle +// the intermediate results while adding or multiplying two 64-bit numbers, and +// second there is no space left for overflows when performing the intermediate +// arithmetic between each array element which would lead to expensive carry +// propagation. +// +// Given the above, this implementation represents the field elements as +// 10 uint32s with each word (array entry) treated as base 2^26. This was +// chosen for the following reasons: +// 1) Most systems at the current time are 64-bit (or at least have 64-bit +// registers available for specialized purposes such as MMX) so the +// intermediate results can typically be done using a native register (and +// using uint64s to avoid the need for additional half-word arithmetic) +// 2) In order to allow addition of the internal words without having to +// propagate the carry, the max normalized value for each register must +// be less than the number of bits available in the register +// 3) Since we're dealing with 32-bit values, 64-bits of overflow is a +// reasonable choice for #2 +// 4) Given the need for 256-bits of precision and the properties stated in #1, +// #2, and #3, the representation which best accommodates this is 10 uint32s +// with base 2^26 (26 bits * 10 = 260 bits, so the final word only needs 22 +// bits) which leaves the desired 64 bits (32 * 10 = 320, 320 - 256 = 64) for +// overflow +// +// Since it is so important that the field arithmetic is extremely fast for high +// performance crypto, this type does not perform any validation where it +// ordinarily would. See the documentation for FieldVal for more details. + +import ( + "encoding/hex" +) + +// Constants used to make the code more readable. +const ( + twoBitsMask = 0x3 + fourBitsMask = 0xf + sixBitsMask = 0x3f + eightBitsMask = 0xff +) + +// Constants related to the field representation. +const ( + // fieldWords is the number of words used to internally represent the + // 256-bit value. + fieldWords = 10 + + // fieldBase is the exponent used to form the numeric base of each word. + // 2^(fieldBase*i) where i is the word position. + fieldBase = 26 + + // fieldBaseMask is the mask for the bits in each word needed to + // represent the numeric base of each word (except the most significant + // word). + fieldBaseMask = (1 << fieldBase) - 1 + + // fieldMSBBits is the number of bits in the most significant word used + // to represent the value. + fieldMSBBits = 256 - (fieldBase * (fieldWords - 1)) + + // fieldMSBMask is the mask for the bits in the most significant word + // needed to represent the value. + fieldMSBMask = (1 << fieldMSBBits) - 1 + + // These fields provide convenient access to each of the words of the + // secp256k1 prime in the internal field representation to improve code + // readability. + fieldPrimeWordZero = 0x03fffc2f + fieldPrimeWordOne = 0x03ffffbf + fieldPrimeWordTwo = 0x03ffffff + fieldPrimeWordThree = 0x03ffffff + fieldPrimeWordFour = 0x03ffffff + fieldPrimeWordFive = 0x03ffffff + fieldPrimeWordSix = 0x03ffffff + fieldPrimeWordSeven = 0x03ffffff + fieldPrimeWordEight = 0x03ffffff + fieldPrimeWordNine = 0x003fffff +) + +// FieldVal implements optimized fixed-precision arithmetic over the +// secp256k1 finite field. This means all arithmetic is performed modulo +// +// 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f. +// +// WARNING: Since it is so important for the field arithmetic to be extremely +// fast for high performance crypto, this type does not perform any validation +// of documented preconditions where it ordinarily would. As a result, it is +// IMPERATIVE for callers to understand some key concepts that are described +// below and ensure the methods are called with the necessary preconditions that +// each method is documented with. For example, some methods only give the +// correct result if the field value is normalized and others require the field +// values involved to have a maximum magnitude and THERE ARE NO EXPLICIT CHECKS +// TO ENSURE THOSE PRECONDITIONS ARE SATISFIED. This does, unfortunately, make +// the type more difficult to use correctly and while I typically prefer to +// ensure all state and input is valid for most code, this is a bit of an +// exception because those extra checks really add up in what ends up being +// critical hot paths. +// +// The first key concept when working with this type is normalization. In order +// to avoid the need to propagate a ton of carries, the internal representation +// provides additional overflow bits for each word of the overall 256-bit value. +// This means that there are multiple internal representations for the same +// value and, as a result, any methods that rely on comparison of the value, +// such as equality and oddness determination, require the caller to provide a +// normalized value. +// +// The second key concept when working with this type is magnitude. As +// previously mentioned, the internal representation provides additional +// overflow bits which means that the more math operations that are performed on +// the field value between normalizations, the more those overflow bits +// accumulate. The magnitude is effectively that maximum possible number of +// those overflow bits that could possibly be required as a result of a given +// operation. Since there are only a limited number of overflow bits available, +// this implies that the max possible magnitude MUST be tracked by the caller +// and the caller MUST normalize the field value if a given operation would +// cause the magnitude of the result to exceed the max allowed value. +// +// IMPORTANT: The max allowed magnitude of a field value is 64. +type FieldVal struct { + // Each 256-bit value is represented as 10 32-bit integers in base 2^26. + // This provides 6 bits of overflow in each word (10 bits in the most + // significant word) for a total of 64 bits of overflow (9*6 + 10 = 64). It + // only implements the arithmetic needed for elliptic curve operations. + // + // The following depicts the internal representation: + // ----------------------------------------------------------------- + // | n[9] | n[8] | ... | n[0] | + // | 32 bits available | 32 bits available | ... | 32 bits available | + // | 22 bits for value | 26 bits for value | ... | 26 bits for value | + // | 10 bits overflow | 6 bits overflow | ... | 6 bits overflow | + // | Mult: 2^(26*9) | Mult: 2^(26*8) | ... | Mult: 2^(26*0) | + // ----------------------------------------------------------------- + // + // For example, consider the number 2^49 + 1. It would be represented as: + // n[0] = 1 + // n[1] = 2^23 + // n[2..9] = 0 + // + // The full 256-bit value is then calculated by looping i from 9..0 and + // doing sum(n[i] * 2^(26i)) like so: + // n[9] * 2^(26*9) = 0 * 2^234 = 0 + // n[8] * 2^(26*8) = 0 * 2^208 = 0 + // ... + // n[1] * 2^(26*1) = 2^23 * 2^26 = 2^49 + // n[0] * 2^(26*0) = 1 * 2^0 = 1 + // Sum: 0 + 0 + ... + 2^49 + 1 = 2^49 + 1 + n [10]uint32 +} + +// String returns the field value as a normalized human-readable hex string. +// +// Preconditions: None +// Output Normalized: Field is not modified -- same as input value +// Output Max Magnitude: Field is not modified -- same as input value +func (f FieldVal) String() string { + // f is a copy, so it's safe to normalize it without mutating the original. + f.Normalize() + return hex.EncodeToString(f.Bytes()[:]) +} + +// Zero sets the field value to zero in constant time. A newly created field +// value is already set to zero. This function can be useful to clear an +// existing field value for reuse. +// +// Preconditions: None +// Output Normalized: Yes +// Output Max Magnitude: 1 +func (f *FieldVal) Zero() { + f.n[0] = 0 + f.n[1] = 0 + f.n[2] = 0 + f.n[3] = 0 + f.n[4] = 0 + f.n[5] = 0 + f.n[6] = 0 + f.n[7] = 0 + f.n[8] = 0 + f.n[9] = 0 +} + +// Set sets the field value equal to the passed value in constant time. The +// normalization and magnitude of the two fields will be identical. +// +// The field value is returned to support chaining. This enables syntax like: +// f := new(FieldVal).Set(f2).Add(1) so that f = f2 + 1 where f2 is not +// modified. +// +// Preconditions: None +// Output Normalized: Same as input value +// Output Max Magnitude: Same as input value +func (f *FieldVal) Set(val *FieldVal) *FieldVal { + *f = *val + return f +} + +// SetInt sets the field value to the passed integer in constant time. This is +// a convenience function since it is fairly common to perform some arithmetic +// with small native integers. +// +// The field value is returned to support chaining. This enables syntax such +// as f := new(FieldVal).SetInt(2).Mul(f2) so that f = 2 * f2. +// +// Preconditions: None +// Output Normalized: Yes +// Output Max Magnitude: 1 +func (f *FieldVal) SetInt(ui uint16) *FieldVal { + f.Zero() + f.n[0] = uint32(ui) + return f +} + +// SetBytes packs the passed 32-byte big-endian value into the internal field +// value representation in constant time. SetBytes interprets the provided +// array as a 256-bit big-endian unsigned integer, packs it into the internal +// field value representation, and returns either 1 if it is greater than or +// equal to the field prime (aka it overflowed) or 0 otherwise in constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. +// +// Preconditions: None +// Output Normalized: Yes if no overflow, no otherwise +// Output Max Magnitude: 1 +func (f *FieldVal) SetBytes(b *[32]byte) uint32 { + // Pack the 256 total bits across the 10 uint32 words with a max of + // 26-bits per word. This could be done with a couple of for loops, + // but this unrolled version is significantly faster. Benchmarks show + // this is about 34 times faster than the variant which uses loops. + f.n[0] = uint32(b[31]) | uint32(b[30])<<8 | uint32(b[29])<<16 | + (uint32(b[28])&twoBitsMask)<<24 + f.n[1] = uint32(b[28])>>2 | uint32(b[27])<<6 | uint32(b[26])<<14 | + (uint32(b[25])&fourBitsMask)<<22 + f.n[2] = uint32(b[25])>>4 | uint32(b[24])<<4 | uint32(b[23])<<12 | + (uint32(b[22])&sixBitsMask)<<20 + f.n[3] = uint32(b[22])>>6 | uint32(b[21])<<2 | uint32(b[20])<<10 | + uint32(b[19])<<18 + f.n[4] = uint32(b[18]) | uint32(b[17])<<8 | uint32(b[16])<<16 | + (uint32(b[15])&twoBitsMask)<<24 + f.n[5] = uint32(b[15])>>2 | uint32(b[14])<<6 | uint32(b[13])<<14 | + (uint32(b[12])&fourBitsMask)<<22 + f.n[6] = uint32(b[12])>>4 | uint32(b[11])<<4 | uint32(b[10])<<12 | + (uint32(b[9])&sixBitsMask)<<20 + f.n[7] = uint32(b[9])>>6 | uint32(b[8])<<2 | uint32(b[7])<<10 | + uint32(b[6])<<18 + f.n[8] = uint32(b[5]) | uint32(b[4])<<8 | uint32(b[3])<<16 | + (uint32(b[2])&twoBitsMask)<<24 + f.n[9] = uint32(b[2])>>2 | uint32(b[1])<<6 | uint32(b[0])<<14 + + // The intuition here is that the field value is greater than the prime if + // one of the higher individual words is greater than corresponding word of + // the prime and all higher words in the field value are equal to their + // corresponding word of the prime. Since this type is modulo the prime, + // being equal is also an overflow back to 0. + // + // Note that because the input is 32 bytes and it was just packed into the + // field representation, the only words that can possibly be greater are + // zero and one, because ceil(log_2(2^256 - 1 - P)) = 33 bits max and the + // internal field representation encodes 26 bits with each word. + // + // Thus, there is no need to test if the upper words of the field value + // exceeds them, hence, only equality is checked for them. + highWordsEq := constantTimeEq(f.n[9], fieldPrimeWordNine) + highWordsEq &= constantTimeEq(f.n[8], fieldPrimeWordEight) + highWordsEq &= constantTimeEq(f.n[7], fieldPrimeWordSeven) + highWordsEq &= constantTimeEq(f.n[6], fieldPrimeWordSix) + highWordsEq &= constantTimeEq(f.n[5], fieldPrimeWordFive) + highWordsEq &= constantTimeEq(f.n[4], fieldPrimeWordFour) + highWordsEq &= constantTimeEq(f.n[3], fieldPrimeWordThree) + highWordsEq &= constantTimeEq(f.n[2], fieldPrimeWordTwo) + overflow := highWordsEq & constantTimeGreater(f.n[1], fieldPrimeWordOne) + highWordsEq &= constantTimeEq(f.n[1], fieldPrimeWordOne) + overflow |= highWordsEq & constantTimeGreaterOrEq(f.n[0], fieldPrimeWordZero) + + return overflow +} + +// SetByteSlice interprets the provided slice as a 256-bit big-endian unsigned +// integer (meaning it is truncated to the first 32 bytes), packs it into the +// internal field value representation, and returns whether or not the resulting +// truncated 256-bit integer is greater than or equal to the field prime (aka it +// overflowed) in constant time. +// +// Note that since passing a slice with more than 32 bytes is truncated, it is +// possible that the truncated value is less than the field prime and hence it +// will not be reported as having overflowed in that case. It is up to the +// caller to decide whether it needs to provide numbers of the appropriate size +// or it if is acceptable to use this function with the described truncation and +// overflow behavior. +// +// Preconditions: None +// Output Normalized: Yes if no overflow, no otherwise +// Output Max Magnitude: 1 +func (f *FieldVal) SetByteSlice(b []byte) bool { + var b32 [32]byte + b = b[:constantTimeMin(uint32(len(b)), 32)] + copy(b32[:], b32[:32-len(b)]) + copy(b32[32-len(b):], b) + result := f.SetBytes(&b32) + zeroArray32(&b32) + return result != 0 +} + +// Normalize normalizes the internal field words into the desired range and +// performs fast modular reduction over the secp256k1 prime by making use of the +// special form of the prime in constant time. +// +// Preconditions: None +// Output Normalized: Yes +// Output Max Magnitude: 1 +func (f *FieldVal) Normalize() *FieldVal { + // The field representation leaves 6 bits of overflow in each word so + // intermediate calculations can be performed without needing to + // propagate the carry to each higher word during the calculations. In + // order to normalize, we need to "compact" the full 256-bit value to + // the right while propagating any carries through to the high order + // word. + // + // Since this field is doing arithmetic modulo the secp256k1 prime, we + // also need to perform modular reduction over the prime. + // + // Per [HAC] section 14.3.4: Reduction method of moduli of special form, + // when the modulus is of the special form m = b^t - c, highly efficient + // reduction can be achieved. + // + // The secp256k1 prime is equivalent to 2^256 - 4294968273, so it fits + // this criteria. + // + // 4294968273 in field representation (base 2^26) is: + // n[0] = 977 + // n[1] = 64 + // That is to say (2^26 * 64) + 977 = 4294968273 + // + // The algorithm presented in the referenced section typically repeats + // until the quotient is zero. However, due to our field representation + // we already know to within one reduction how many times we would need + // to repeat as it's the uppermost bits of the high order word. Thus we + // can simply multiply the magnitude by the field representation of the + // prime and do a single iteration. After this step there might be an + // additional carry to bit 256 (bit 22 of the high order word). + t9 := f.n[9] + m := t9 >> fieldMSBBits + t9 = t9 & fieldMSBMask + t0 := f.n[0] + m*977 + t1 := (t0 >> fieldBase) + f.n[1] + (m << 6) + t0 = t0 & fieldBaseMask + t2 := (t1 >> fieldBase) + f.n[2] + t1 = t1 & fieldBaseMask + t3 := (t2 >> fieldBase) + f.n[3] + t2 = t2 & fieldBaseMask + t4 := (t3 >> fieldBase) + f.n[4] + t3 = t3 & fieldBaseMask + t5 := (t4 >> fieldBase) + f.n[5] + t4 = t4 & fieldBaseMask + t6 := (t5 >> fieldBase) + f.n[6] + t5 = t5 & fieldBaseMask + t7 := (t6 >> fieldBase) + f.n[7] + t6 = t6 & fieldBaseMask + t8 := (t7 >> fieldBase) + f.n[8] + t7 = t7 & fieldBaseMask + t9 = (t8 >> fieldBase) + t9 + t8 = t8 & fieldBaseMask + + // At this point, the magnitude is guaranteed to be one, however, the + // value could still be greater than the prime if there was either a + // carry through to bit 256 (bit 22 of the higher order word) or the + // value is greater than or equal to the field characteristic. The + // following determines if either or these conditions are true and does + // the final reduction in constant time. + // + // Also note that 'm' will be zero when neither of the aforementioned + // conditions are true and the value will not be changed when 'm' is zero. + m = constantTimeEq(t9, fieldMSBMask) + m &= constantTimeEq(t8&t7&t6&t5&t4&t3&t2, fieldBaseMask) + m &= constantTimeGreater(t1+64+((t0+977)>>fieldBase), fieldBaseMask) + m |= t9 >> fieldMSBBits + t0 = t0 + m*977 + t1 = (t0 >> fieldBase) + t1 + (m << 6) + t0 = t0 & fieldBaseMask + t2 = (t1 >> fieldBase) + t2 + t1 = t1 & fieldBaseMask + t3 = (t2 >> fieldBase) + t3 + t2 = t2 & fieldBaseMask + t4 = (t3 >> fieldBase) + t4 + t3 = t3 & fieldBaseMask + t5 = (t4 >> fieldBase) + t5 + t4 = t4 & fieldBaseMask + t6 = (t5 >> fieldBase) + t6 + t5 = t5 & fieldBaseMask + t7 = (t6 >> fieldBase) + t7 + t6 = t6 & fieldBaseMask + t8 = (t7 >> fieldBase) + t8 + t7 = t7 & fieldBaseMask + t9 = (t8 >> fieldBase) + t9 + t8 = t8 & fieldBaseMask + t9 = t9 & fieldMSBMask // Remove potential multiple of 2^256. + + // Finally, set the normalized and reduced words. + f.n[0] = t0 + f.n[1] = t1 + f.n[2] = t2 + f.n[3] = t3 + f.n[4] = t4 + f.n[5] = t5 + f.n[6] = t6 + f.n[7] = t7 + f.n[8] = t8 + f.n[9] = t9 + return f +} + +// PutBytesUnchecked unpacks the field value to a 32-byte big-endian value +// directly into the passed byte slice in constant time. The target slice must +// must have at least 32 bytes available or it will panic. +// +// There is a similar function, PutBytes, which unpacks the field value into a +// 32-byte array directly. This version is provided since it can be useful +// to write directly into part of a larger buffer without needing a separate +// allocation. +// +// Preconditions: +// - The field value MUST be normalized +// - The target slice MUST have at least 32 bytes available +func (f *FieldVal) PutBytesUnchecked(b []byte) { + // Unpack the 256 total bits from the 10 uint32 words with a max of + // 26-bits per word. This could be done with a couple of for loops, + // but this unrolled version is a bit faster. Benchmarks show this is + // about 10 times faster than the variant which uses loops. + b[31] = byte(f.n[0] & eightBitsMask) + b[30] = byte((f.n[0] >> 8) & eightBitsMask) + b[29] = byte((f.n[0] >> 16) & eightBitsMask) + b[28] = byte((f.n[0]>>24)&twoBitsMask | (f.n[1]&sixBitsMask)<<2) + b[27] = byte((f.n[1] >> 6) & eightBitsMask) + b[26] = byte((f.n[1] >> 14) & eightBitsMask) + b[25] = byte((f.n[1]>>22)&fourBitsMask | (f.n[2]&fourBitsMask)<<4) + b[24] = byte((f.n[2] >> 4) & eightBitsMask) + b[23] = byte((f.n[2] >> 12) & eightBitsMask) + b[22] = byte((f.n[2]>>20)&sixBitsMask | (f.n[3]&twoBitsMask)<<6) + b[21] = byte((f.n[3] >> 2) & eightBitsMask) + b[20] = byte((f.n[3] >> 10) & eightBitsMask) + b[19] = byte((f.n[3] >> 18) & eightBitsMask) + b[18] = byte(f.n[4] & eightBitsMask) + b[17] = byte((f.n[4] >> 8) & eightBitsMask) + b[16] = byte((f.n[4] >> 16) & eightBitsMask) + b[15] = byte((f.n[4]>>24)&twoBitsMask | (f.n[5]&sixBitsMask)<<2) + b[14] = byte((f.n[5] >> 6) & eightBitsMask) + b[13] = byte((f.n[5] >> 14) & eightBitsMask) + b[12] = byte((f.n[5]>>22)&fourBitsMask | (f.n[6]&fourBitsMask)<<4) + b[11] = byte((f.n[6] >> 4) & eightBitsMask) + b[10] = byte((f.n[6] >> 12) & eightBitsMask) + b[9] = byte((f.n[6]>>20)&sixBitsMask | (f.n[7]&twoBitsMask)<<6) + b[8] = byte((f.n[7] >> 2) & eightBitsMask) + b[7] = byte((f.n[7] >> 10) & eightBitsMask) + b[6] = byte((f.n[7] >> 18) & eightBitsMask) + b[5] = byte(f.n[8] & eightBitsMask) + b[4] = byte((f.n[8] >> 8) & eightBitsMask) + b[3] = byte((f.n[8] >> 16) & eightBitsMask) + b[2] = byte((f.n[8]>>24)&twoBitsMask | (f.n[9]&sixBitsMask)<<2) + b[1] = byte((f.n[9] >> 6) & eightBitsMask) + b[0] = byte((f.n[9] >> 14) & eightBitsMask) +} + +// PutBytes unpacks the field value to a 32-byte big-endian value using the +// passed byte array in constant time. +// +// There is a similar function, PutBytesUnchecked, which unpacks the field value +// into a slice that must have at least 32 bytes available. This version is +// provided since it can be useful to write directly into an array that is type +// checked. +// +// Alternatively, there is also Bytes, which unpacks the field value into a new +// array and returns that which can sometimes be more ergonomic in applications +// that aren't concerned about an additional copy. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) PutBytes(b *[32]byte) { + f.PutBytesUnchecked(b[:]) +} + +// Bytes unpacks the field value to a 32-byte big-endian value in constant time. +// +// See PutBytes and PutBytesUnchecked for variants that allow an array or slice +// to be passed which can be useful to cut down on the number of allocations by +// allowing the caller to reuse a buffer or write directly into part of a larger +// buffer. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) Bytes() *[32]byte { + b := new([32]byte) + f.PutBytesUnchecked(b[:]) + return b +} + +// IsZeroBit returns 1 when the field value is equal to zero or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. See IsZero for the version that returns +// a bool. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsZeroBit() uint32 { + // The value can only be zero if no bits are set in any of the words. + // This is a constant time implementation. + bits := f.n[0] | f.n[1] | f.n[2] | f.n[3] | f.n[4] | + f.n[5] | f.n[6] | f.n[7] | f.n[8] | f.n[9] + + return constantTimeEq(bits, 0) +} + +// IsZero returns whether or not the field value is equal to zero in constant +// time. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsZero() bool { + // The value can only be zero if no bits are set in any of the words. + // This is a constant time implementation. + bits := f.n[0] | f.n[1] | f.n[2] | f.n[3] | f.n[4] | + f.n[5] | f.n[6] | f.n[7] | f.n[8] | f.n[9] + + return bits == 0 +} + +// IsOneBit returns 1 when the field value is equal to one or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. See IsOne for the version that returns a +// bool. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsOneBit() uint32 { + // The value can only be one if the single lowest significant bit is set in + // the first word and no other bits are set in any of the other words. + // This is a constant time implementation. + bits := (f.n[0] ^ 1) | f.n[1] | f.n[2] | f.n[3] | f.n[4] | f.n[5] | + f.n[6] | f.n[7] | f.n[8] | f.n[9] + + return constantTimeEq(bits, 0) +} + +// IsOne returns whether or not the field value is equal to one in constant +// time. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsOne() bool { + // The value can only be one if the single lowest significant bit is set in + // the first word and no other bits are set in any of the other words. + // This is a constant time implementation. + bits := (f.n[0] ^ 1) | f.n[1] | f.n[2] | f.n[3] | f.n[4] | f.n[5] | + f.n[6] | f.n[7] | f.n[8] | f.n[9] + + return bits == 0 +} + +// IsOddBit returns 1 when the field value is an odd number or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. See IsOdd for the version that returns a +// bool. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsOddBit() uint32 { + // Only odd numbers have the bottom bit set. + return f.n[0] & 1 +} + +// IsOdd returns whether or not the field value is an odd number in constant +// time. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsOdd() bool { + // Only odd numbers have the bottom bit set. + return f.n[0]&1 == 1 +} + +// Equals returns whether or not the two field values are the same in constant +// time. +// +// Preconditions: +// - Both field values being compared MUST be normalized +func (f *FieldVal) Equals(val *FieldVal) bool { + // Xor only sets bits when they are different, so the two field values + // can only be the same if no bits are set after xoring each word. + // This is a constant time implementation. + bits := (f.n[0] ^ val.n[0]) | (f.n[1] ^ val.n[1]) | (f.n[2] ^ val.n[2]) | + (f.n[3] ^ val.n[3]) | (f.n[4] ^ val.n[4]) | (f.n[5] ^ val.n[5]) | + (f.n[6] ^ val.n[6]) | (f.n[7] ^ val.n[7]) | (f.n[8] ^ val.n[8]) | + (f.n[9] ^ val.n[9]) + + return bits == 0 +} + +// NegateVal negates the passed value and stores the result in f in constant +// time. The caller must provide the magnitude of the passed value for a +// correct result. +// +// The field value is returned to support chaining. This enables syntax like: +// f.NegateVal(f2).AddInt(1) so that f = -f2 + 1. +// +// Preconditions: +// - The max magnitude MUST be 63 +// Output Normalized: No +// Output Max Magnitude: Input magnitude + 1 +func (f *FieldVal) NegateVal(val *FieldVal, magnitude uint32) *FieldVal { + // Negation in the field is just the prime minus the value. However, + // in order to allow negation against a field value without having to + // normalize/reduce it first, multiply by the magnitude (that is how + // "far" away it is from the normalized value) to adjust. Also, since + // negating a value pushes it one more order of magnitude away from the + // normalized range, add 1 to compensate. + // + // For some intuition here, imagine you're performing mod 12 arithmetic + // (picture a clock) and you are negating the number 7. So you start at + // 12 (which is of course 0 under mod 12) and count backwards (left on + // the clock) 7 times to arrive at 5. Notice this is just 12-7 = 5. + // Now, assume you're starting with 19, which is a number that is + // already larger than the modulus and congruent to 7 (mod 12). When a + // value is already in the desired range, its magnitude is 1. Since 19 + // is an additional "step", its magnitude (mod 12) is 2. Since any + // multiple of the modulus is congruent to zero (mod m), the answer can + // be shortcut by simply multiplying the magnitude by the modulus and + // subtracting. Keeping with the example, this would be (2*12)-19 = 5. + f.n[0] = (magnitude+1)*fieldPrimeWordZero - val.n[0] + f.n[1] = (magnitude+1)*fieldPrimeWordOne - val.n[1] + f.n[2] = (magnitude+1)*fieldBaseMask - val.n[2] + f.n[3] = (magnitude+1)*fieldBaseMask - val.n[3] + f.n[4] = (magnitude+1)*fieldBaseMask - val.n[4] + f.n[5] = (magnitude+1)*fieldBaseMask - val.n[5] + f.n[6] = (magnitude+1)*fieldBaseMask - val.n[6] + f.n[7] = (magnitude+1)*fieldBaseMask - val.n[7] + f.n[8] = (magnitude+1)*fieldBaseMask - val.n[8] + f.n[9] = (magnitude+1)*fieldMSBMask - val.n[9] + + return f +} + +// Negate negates the field value in constant time. The existing field value is +// modified. The caller must provide the magnitude of the field value for a +// correct result. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Negate().AddInt(1) so that f = -f + 1. +// +// Preconditions: +// - The max magnitude MUST be 63 +// Output Normalized: No +// Output Max Magnitude: Input magnitude + 1 +func (f *FieldVal) Negate(magnitude uint32) *FieldVal { + return f.NegateVal(f, magnitude) +} + +// AddInt adds the passed integer to the existing field value and stores the +// result in f in constant time. This is a convenience function since it is +// fairly common to perform some arithmetic with small native integers. +// +// The field value is returned to support chaining. This enables syntax like: +// f.AddInt(1).Add(f2) so that f = f + 1 + f2. +// +// Preconditions: +// - The field value MUST have a max magnitude of 63 +// Output Normalized: No +// Output Max Magnitude: Existing field magnitude + 1 +func (f *FieldVal) AddInt(ui uint16) *FieldVal { + // Since the field representation intentionally provides overflow bits, + // it's ok to use carryless addition as the carry bit is safely part of + // the word and will be normalized out. + f.n[0] += uint32(ui) + + return f +} + +// Add adds the passed value to the existing field value and stores the result +// in f in constant time. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Add(f2).AddInt(1) so that f = f + f2 + 1. +// +// Preconditions: +// - The sum of the magnitudes of the two field values MUST be a max of 64 +// Output Normalized: No +// Output Max Magnitude: Sum of the magnitude of the two individual field values +func (f *FieldVal) Add(val *FieldVal) *FieldVal { + // Since the field representation intentionally provides overflow bits, + // it's ok to use carryless addition as the carry bit is safely part of + // each word and will be normalized out. This could obviously be done + // in a loop, but the unrolled version is faster. + f.n[0] += val.n[0] + f.n[1] += val.n[1] + f.n[2] += val.n[2] + f.n[3] += val.n[3] + f.n[4] += val.n[4] + f.n[5] += val.n[5] + f.n[6] += val.n[6] + f.n[7] += val.n[7] + f.n[8] += val.n[8] + f.n[9] += val.n[9] + + return f +} + +// Add2 adds the passed two field values together and stores the result in f in +// constant time. +// +// The field value is returned to support chaining. This enables syntax like: +// f3.Add2(f, f2).AddInt(1) so that f3 = f + f2 + 1. +// +// Preconditions: +// - The sum of the magnitudes of the two field values MUST be a max of 64 +// Output Normalized: No +// Output Max Magnitude: Sum of the magnitude of the two field values +func (f *FieldVal) Add2(val *FieldVal, val2 *FieldVal) *FieldVal { + // Since the field representation intentionally provides overflow bits, + // it's ok to use carryless addition as the carry bit is safely part of + // each word and will be normalized out. This could obviously be done + // in a loop, but the unrolled version is faster. + f.n[0] = val.n[0] + val2.n[0] + f.n[1] = val.n[1] + val2.n[1] + f.n[2] = val.n[2] + val2.n[2] + f.n[3] = val.n[3] + val2.n[3] + f.n[4] = val.n[4] + val2.n[4] + f.n[5] = val.n[5] + val2.n[5] + f.n[6] = val.n[6] + val2.n[6] + f.n[7] = val.n[7] + val2.n[7] + f.n[8] = val.n[8] + val2.n[8] + f.n[9] = val.n[9] + val2.n[9] + + return f +} + +// MulInt multiplies the field value by the passed int and stores the result in +// f in constant time. Note that this function can overflow if multiplying the +// value by any of the individual words exceeds a max uint32. Therefore it is +// important that the caller ensures no overflows will occur before using this +// function. +// +// The field value is returned to support chaining. This enables syntax like: +// f.MulInt(2).Add(f2) so that f = 2 * f + f2. +// +// Preconditions: +// - The field value magnitude multiplied by given val MUST be a max of 64 +// Output Normalized: No +// Output Max Magnitude: Existing field magnitude times the provided integer val +func (f *FieldVal) MulInt(val uint8) *FieldVal { + // Since each word of the field representation can hold up to + // 32 - fieldBase extra bits which will be normalized out, it's safe + // to multiply each word without using a larger type or carry + // propagation so long as the values won't overflow a uint32. This + // could obviously be done in a loop, but the unrolled version is + // faster. + ui := uint32(val) + f.n[0] *= ui + f.n[1] *= ui + f.n[2] *= ui + f.n[3] *= ui + f.n[4] *= ui + f.n[5] *= ui + f.n[6] *= ui + f.n[7] *= ui + f.n[8] *= ui + f.n[9] *= ui + + return f +} + +// Mul multiplies the passed value to the existing field value and stores the +// result in f in constant time. Note that this function can overflow if +// multiplying any of the individual words exceeds a max uint32. In practice, +// this means the magnitude of either value involved in the multiplication must +// be a max of 8. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Mul(f2).AddInt(1) so that f = (f * f2) + 1. +// +// Preconditions: +// - Both field values MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) Mul(val *FieldVal) *FieldVal { + return f.Mul2(f, val) +} + +// Mul2 multiplies the passed two field values together and stores the result +// result in f in constant time. Note that this function can overflow if +// multiplying any of the individual words exceeds a max uint32. In practice, +// this means the magnitude of either value involved in the multiplication must +// be a max of 8. +// +// The field value is returned to support chaining. This enables syntax like: +// f3.Mul2(f, f2).AddInt(1) so that f3 = (f * f2) + 1. +// +// Preconditions: +// - Both input field values MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) Mul2(val *FieldVal, val2 *FieldVal) *FieldVal { + // This could be done with a couple of for loops and an array to store + // the intermediate terms, but this unrolled version is significantly + // faster. + + // Terms for 2^(fieldBase*0). + m := uint64(val.n[0]) * uint64(val2.n[0]) + t0 := m & fieldBaseMask + + // Terms for 2^(fieldBase*1). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[1]) + + uint64(val.n[1])*uint64(val2.n[0]) + t1 := m & fieldBaseMask + + // Terms for 2^(fieldBase*2). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[2]) + + uint64(val.n[1])*uint64(val2.n[1]) + + uint64(val.n[2])*uint64(val2.n[0]) + t2 := m & fieldBaseMask + + // Terms for 2^(fieldBase*3). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[3]) + + uint64(val.n[1])*uint64(val2.n[2]) + + uint64(val.n[2])*uint64(val2.n[1]) + + uint64(val.n[3])*uint64(val2.n[0]) + t3 := m & fieldBaseMask + + // Terms for 2^(fieldBase*4). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[4]) + + uint64(val.n[1])*uint64(val2.n[3]) + + uint64(val.n[2])*uint64(val2.n[2]) + + uint64(val.n[3])*uint64(val2.n[1]) + + uint64(val.n[4])*uint64(val2.n[0]) + t4 := m & fieldBaseMask + + // Terms for 2^(fieldBase*5). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[5]) + + uint64(val.n[1])*uint64(val2.n[4]) + + uint64(val.n[2])*uint64(val2.n[3]) + + uint64(val.n[3])*uint64(val2.n[2]) + + uint64(val.n[4])*uint64(val2.n[1]) + + uint64(val.n[5])*uint64(val2.n[0]) + t5 := m & fieldBaseMask + + // Terms for 2^(fieldBase*6). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[6]) + + uint64(val.n[1])*uint64(val2.n[5]) + + uint64(val.n[2])*uint64(val2.n[4]) + + uint64(val.n[3])*uint64(val2.n[3]) + + uint64(val.n[4])*uint64(val2.n[2]) + + uint64(val.n[5])*uint64(val2.n[1]) + + uint64(val.n[6])*uint64(val2.n[0]) + t6 := m & fieldBaseMask + + // Terms for 2^(fieldBase*7). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[7]) + + uint64(val.n[1])*uint64(val2.n[6]) + + uint64(val.n[2])*uint64(val2.n[5]) + + uint64(val.n[3])*uint64(val2.n[4]) + + uint64(val.n[4])*uint64(val2.n[3]) + + uint64(val.n[5])*uint64(val2.n[2]) + + uint64(val.n[6])*uint64(val2.n[1]) + + uint64(val.n[7])*uint64(val2.n[0]) + t7 := m & fieldBaseMask + + // Terms for 2^(fieldBase*8). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[8]) + + uint64(val.n[1])*uint64(val2.n[7]) + + uint64(val.n[2])*uint64(val2.n[6]) + + uint64(val.n[3])*uint64(val2.n[5]) + + uint64(val.n[4])*uint64(val2.n[4]) + + uint64(val.n[5])*uint64(val2.n[3]) + + uint64(val.n[6])*uint64(val2.n[2]) + + uint64(val.n[7])*uint64(val2.n[1]) + + uint64(val.n[8])*uint64(val2.n[0]) + t8 := m & fieldBaseMask + + // Terms for 2^(fieldBase*9). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[9]) + + uint64(val.n[1])*uint64(val2.n[8]) + + uint64(val.n[2])*uint64(val2.n[7]) + + uint64(val.n[3])*uint64(val2.n[6]) + + uint64(val.n[4])*uint64(val2.n[5]) + + uint64(val.n[5])*uint64(val2.n[4]) + + uint64(val.n[6])*uint64(val2.n[3]) + + uint64(val.n[7])*uint64(val2.n[2]) + + uint64(val.n[8])*uint64(val2.n[1]) + + uint64(val.n[9])*uint64(val2.n[0]) + t9 := m & fieldBaseMask + + // Terms for 2^(fieldBase*10). + m = (m >> fieldBase) + + uint64(val.n[1])*uint64(val2.n[9]) + + uint64(val.n[2])*uint64(val2.n[8]) + + uint64(val.n[3])*uint64(val2.n[7]) + + uint64(val.n[4])*uint64(val2.n[6]) + + uint64(val.n[5])*uint64(val2.n[5]) + + uint64(val.n[6])*uint64(val2.n[4]) + + uint64(val.n[7])*uint64(val2.n[3]) + + uint64(val.n[8])*uint64(val2.n[2]) + + uint64(val.n[9])*uint64(val2.n[1]) + t10 := m & fieldBaseMask + + // Terms for 2^(fieldBase*11). + m = (m >> fieldBase) + + uint64(val.n[2])*uint64(val2.n[9]) + + uint64(val.n[3])*uint64(val2.n[8]) + + uint64(val.n[4])*uint64(val2.n[7]) + + uint64(val.n[5])*uint64(val2.n[6]) + + uint64(val.n[6])*uint64(val2.n[5]) + + uint64(val.n[7])*uint64(val2.n[4]) + + uint64(val.n[8])*uint64(val2.n[3]) + + uint64(val.n[9])*uint64(val2.n[2]) + t11 := m & fieldBaseMask + + // Terms for 2^(fieldBase*12). + m = (m >> fieldBase) + + uint64(val.n[3])*uint64(val2.n[9]) + + uint64(val.n[4])*uint64(val2.n[8]) + + uint64(val.n[5])*uint64(val2.n[7]) + + uint64(val.n[6])*uint64(val2.n[6]) + + uint64(val.n[7])*uint64(val2.n[5]) + + uint64(val.n[8])*uint64(val2.n[4]) + + uint64(val.n[9])*uint64(val2.n[3]) + t12 := m & fieldBaseMask + + // Terms for 2^(fieldBase*13). + m = (m >> fieldBase) + + uint64(val.n[4])*uint64(val2.n[9]) + + uint64(val.n[5])*uint64(val2.n[8]) + + uint64(val.n[6])*uint64(val2.n[7]) + + uint64(val.n[7])*uint64(val2.n[6]) + + uint64(val.n[8])*uint64(val2.n[5]) + + uint64(val.n[9])*uint64(val2.n[4]) + t13 := m & fieldBaseMask + + // Terms for 2^(fieldBase*14). + m = (m >> fieldBase) + + uint64(val.n[5])*uint64(val2.n[9]) + + uint64(val.n[6])*uint64(val2.n[8]) + + uint64(val.n[7])*uint64(val2.n[7]) + + uint64(val.n[8])*uint64(val2.n[6]) + + uint64(val.n[9])*uint64(val2.n[5]) + t14 := m & fieldBaseMask + + // Terms for 2^(fieldBase*15). + m = (m >> fieldBase) + + uint64(val.n[6])*uint64(val2.n[9]) + + uint64(val.n[7])*uint64(val2.n[8]) + + uint64(val.n[8])*uint64(val2.n[7]) + + uint64(val.n[9])*uint64(val2.n[6]) + t15 := m & fieldBaseMask + + // Terms for 2^(fieldBase*16). + m = (m >> fieldBase) + + uint64(val.n[7])*uint64(val2.n[9]) + + uint64(val.n[8])*uint64(val2.n[8]) + + uint64(val.n[9])*uint64(val2.n[7]) + t16 := m & fieldBaseMask + + // Terms for 2^(fieldBase*17). + m = (m >> fieldBase) + + uint64(val.n[8])*uint64(val2.n[9]) + + uint64(val.n[9])*uint64(val2.n[8]) + t17 := m & fieldBaseMask + + // Terms for 2^(fieldBase*18). + m = (m >> fieldBase) + uint64(val.n[9])*uint64(val2.n[9]) + t18 := m & fieldBaseMask + + // What's left is for 2^(fieldBase*19). + t19 := m >> fieldBase + + // At this point, all of the terms are grouped into their respective + // base. + // + // Per [HAC] section 14.3.4: Reduction method of moduli of special form, + // when the modulus is of the special form m = b^t - c, highly efficient + // reduction can be achieved per the provided algorithm. + // + // The secp256k1 prime is equivalent to 2^256 - 4294968273, so it fits + // this criteria. + // + // 4294968273 in field representation (base 2^26) is: + // n[0] = 977 + // n[1] = 64 + // That is to say (2^26 * 64) + 977 = 4294968273 + // + // Since each word is in base 26, the upper terms (t10 and up) start + // at 260 bits (versus the final desired range of 256 bits), so the + // field representation of 'c' from above needs to be adjusted for the + // extra 4 bits by multiplying it by 2^4 = 16. 4294968273 * 16 = + // 68719492368. Thus, the adjusted field representation of 'c' is: + // n[0] = 977 * 16 = 15632 + // n[1] = 64 * 16 = 1024 + // That is to say (2^26 * 1024) + 15632 = 68719492368 + // + // To reduce the final term, t19, the entire 'c' value is needed instead + // of only n[0] because there are no more terms left to handle n[1]. + // This means there might be some magnitude left in the upper bits that + // is handled below. + m = t0 + t10*15632 + t0 = m & fieldBaseMask + m = (m >> fieldBase) + t1 + t10*1024 + t11*15632 + t1 = m & fieldBaseMask + m = (m >> fieldBase) + t2 + t11*1024 + t12*15632 + t2 = m & fieldBaseMask + m = (m >> fieldBase) + t3 + t12*1024 + t13*15632 + t3 = m & fieldBaseMask + m = (m >> fieldBase) + t4 + t13*1024 + t14*15632 + t4 = m & fieldBaseMask + m = (m >> fieldBase) + t5 + t14*1024 + t15*15632 + t5 = m & fieldBaseMask + m = (m >> fieldBase) + t6 + t15*1024 + t16*15632 + t6 = m & fieldBaseMask + m = (m >> fieldBase) + t7 + t16*1024 + t17*15632 + t7 = m & fieldBaseMask + m = (m >> fieldBase) + t8 + t17*1024 + t18*15632 + t8 = m & fieldBaseMask + m = (m >> fieldBase) + t9 + t18*1024 + t19*68719492368 + t9 = m & fieldMSBMask + m = m >> fieldMSBBits + + // At this point, if the magnitude is greater than 0, the overall value + // is greater than the max possible 256-bit value. In particular, it is + // "how many times larger" than the max value it is. + // + // The algorithm presented in [HAC] section 14.3.4 repeats until the + // quotient is zero. However, due to the above, we already know at + // least how many times we would need to repeat as it's the value + // currently in m. Thus we can simply multiply the magnitude by the + // field representation of the prime and do a single iteration. Notice + // that nothing will be changed when the magnitude is zero, so we could + // skip this in that case, however always running regardless allows it + // to run in constant time. The final result will be in the range + // 0 <= result <= prime + (2^64 - c), so it is guaranteed to have a + // magnitude of 1, but it is denormalized. + d := t0 + m*977 + f.n[0] = uint32(d & fieldBaseMask) + d = (d >> fieldBase) + t1 + m*64 + f.n[1] = uint32(d & fieldBaseMask) + f.n[2] = uint32((d >> fieldBase) + t2) + f.n[3] = uint32(t3) + f.n[4] = uint32(t4) + f.n[5] = uint32(t5) + f.n[6] = uint32(t6) + f.n[7] = uint32(t7) + f.n[8] = uint32(t8) + f.n[9] = uint32(t9) + + return f +} + +// SquareRootVal either calculates the square root of the passed value when it +// exists or the square root of the negation of the value when it does not exist +// and stores the result in f in constant time. The return flag is true when +// the calculated square root is for the passed value itself and false when it +// is for its negation. +// +// Note that this function can overflow if multiplying any of the individual +// words exceeds a max uint32. In practice, this means the magnitude of the +// field must be a max of 8 to prevent overflow. The magnitude of the result +// will be 1. +// +// Preconditions: +// - The input field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) SquareRootVal(val *FieldVal) bool { + // This uses the Tonelli-Shanks method for calculating the square root of + // the value when it exists. The key principles of the method follow. + // + // Fermat's little theorem states that for a nonzero number 'a' and prime + // 'p', a^(p-1) ≡ 1 (mod p). + // + // Further, Euler's criterion states that an integer 'a' has a square root + // (aka is a quadratic residue) modulo a prime if a^((p-1)/2) ≡ 1 (mod p) + // and, conversely, when it does NOT have a square root (aka 'a' is a + // non-residue) a^((p-1)/2) ≡ -1 (mod p). + // + // This can be seen by considering that Fermat's little theorem can be + // written as (a^((p-1)/2) - 1)(a^((p-1)/2) + 1) ≡ 0 (mod p). Therefore, + // one of the two factors must be 0. Then, when a ≡ x^2 (aka 'a' is a + // quadratic residue), (x^2)^((p-1)/2) ≡ x^(p-1) ≡ 1 (mod p) which implies + // the first factor must be zero. Finally, per Lagrange's theorem, the + // non-residues are the only remaining possible solutions and thus must make + // the second factor zero to satisfy Fermat's little theorem implying that + // a^((p-1)/2) ≡ -1 (mod p) for that case. + // + // The Tonelli-Shanks method uses these facts along with factoring out + // powers of two to solve a congruence that results in either the solution + // when the square root exists or the square root of the negation of the + // value when it does not. In the case of primes that are ≡ 3 (mod 4), the + // possible solutions are r = ±a^((p+1)/4) (mod p). Therefore, either r^2 ≡ + // a (mod p) is true in which case ±r are the two solutions, or r^2 ≡ -a + // (mod p) in which case 'a' is a non-residue and there are no solutions. + // + // The secp256k1 prime is ≡ 3 (mod 4), so this result applies. + // + // In other words, calculate a^((p+1)/4) and then square it and check it + // against the original value to determine if it is actually the square + // root. + // + // In order to efficiently compute a^((p+1)/4), (p+1)/4 needs to be split + // into a sequence of squares and multiplications that minimizes the number + // of multiplications needed (since they are more costly than squarings). + // + // The secp256k1 prime + 1 / 4 is 2^254 - 2^30 - 244. In binary, that is: + // + // 00111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 10111111 11111111 11111111 00001100 + // + // Notice that can be broken up into three windows of consecutive 1s (in + // order of least to most significant) as: + // + // 6-bit window with two bits set (bits 4, 5, 6, 7 unset) + // 23-bit window with 22 bits set (bit 30 unset) + // 223-bit window with all 223 bits set + // + // Thus, the groups of 1 bits in each window forms the set: + // S = {2, 22, 223}. + // + // The strategy is to calculate a^(2^n - 1) for each grouping via an + // addition chain with a sliding window. + // + // The addition chain used is (credits to Peter Dettman): + // (0,0),(1,0),(2,2),(3,2),(4,1),(5,5),(6,6),(7,7),(8,8),(9,7),(10,2) + // => 2^1 2^[2] 2^3 2^6 2^9 2^11 2^[22] 2^44 2^88 2^176 2^220 2^[223] + // + // This has a cost of 254 field squarings and 13 field multiplications. + var a, a2, a3, a6, a9, a11, a22, a44, a88, a176, a220, a223 FieldVal + a.Set(val) + a2.SquareVal(&a).Mul(&a) // a2 = a^(2^2 - 1) + a3.SquareVal(&a2).Mul(&a) // a3 = a^(2^3 - 1) + a6.SquareVal(&a3).Square().Square() // a6 = a^(2^6 - 2^3) + a6.Mul(&a3) // a6 = a^(2^6 - 1) + a9.SquareVal(&a6).Square().Square() // a9 = a^(2^9 - 2^3) + a9.Mul(&a3) // a9 = a^(2^9 - 1) + a11.SquareVal(&a9).Square() // a11 = a^(2^11 - 2^2) + a11.Mul(&a2) // a11 = a^(2^11 - 1) + a22.SquareVal(&a11).Square().Square().Square().Square() // a22 = a^(2^16 - 2^5) + a22.Square().Square().Square().Square().Square() // a22 = a^(2^21 - 2^10) + a22.Square() // a22 = a^(2^22 - 2^11) + a22.Mul(&a11) // a22 = a^(2^22 - 1) + a44.SquareVal(&a22).Square().Square().Square().Square() // a44 = a^(2^27 - 2^5) + a44.Square().Square().Square().Square().Square() // a44 = a^(2^32 - 2^10) + a44.Square().Square().Square().Square().Square() // a44 = a^(2^37 - 2^15) + a44.Square().Square().Square().Square().Square() // a44 = a^(2^42 - 2^20) + a44.Square().Square() // a44 = a^(2^44 - 2^22) + a44.Mul(&a22) // a44 = a^(2^44 - 1) + a88.SquareVal(&a44).Square().Square().Square().Square() // a88 = a^(2^49 - 2^5) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^54 - 2^10) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^59 - 2^15) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^64 - 2^20) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^69 - 2^25) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^74 - 2^30) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^79 - 2^35) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^84 - 2^40) + a88.Square().Square().Square().Square() // a88 = a^(2^88 - 2^44) + a88.Mul(&a44) // a88 = a^(2^88 - 1) + a176.SquareVal(&a88).Square().Square().Square().Square() // a176 = a^(2^93 - 2^5) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^98 - 2^10) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^103 - 2^15) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^108 - 2^20) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^113 - 2^25) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^118 - 2^30) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^123 - 2^35) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^128 - 2^40) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^133 - 2^45) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^138 - 2^50) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^143 - 2^55) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^148 - 2^60) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^153 - 2^65) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^158 - 2^70) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^163 - 2^75) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^168 - 2^80) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^173 - 2^85) + a176.Square().Square().Square() // a176 = a^(2^176 - 2^88) + a176.Mul(&a88) // a176 = a^(2^176 - 1) + a220.SquareVal(&a176).Square().Square().Square().Square() // a220 = a^(2^181 - 2^5) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^186 - 2^10) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^191 - 2^15) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^196 - 2^20) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^201 - 2^25) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^206 - 2^30) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^211 - 2^35) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^216 - 2^40) + a220.Square().Square().Square().Square() // a220 = a^(2^220 - 2^44) + a220.Mul(&a44) // a220 = a^(2^220 - 1) + a223.SquareVal(&a220).Square().Square() // a223 = a^(2^223 - 2^3) + a223.Mul(&a3) // a223 = a^(2^223 - 1) + + f.SquareVal(&a223).Square().Square().Square().Square() // f = a^(2^228 - 2^5) + f.Square().Square().Square().Square().Square() // f = a^(2^233 - 2^10) + f.Square().Square().Square().Square().Square() // f = a^(2^238 - 2^15) + f.Square().Square().Square().Square().Square() // f = a^(2^243 - 2^20) + f.Square().Square().Square() // f = a^(2^246 - 2^23) + f.Mul(&a22) // f = a^(2^246 - 2^22 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^251 - 2^27 - 2^5) + f.Square() // f = a^(2^252 - 2^28 - 2^6) + f.Mul(&a2) // f = a^(2^252 - 2^28 - 2^6 - 2^1 - 1) + f.Square().Square() // f = a^(2^254 - 2^30 - 2^8 - 2^3 - 2^2) + // // = a^(2^254 - 2^30 - 244) + // // = a^((p+1)/4) + + // Ensure the calculated result is actually the square root by squaring it + // and checking against the original value. + var sqr FieldVal + return sqr.SquareVal(f).Normalize().Equals(val.Normalize()) +} + +// Square squares the field value in constant time. The existing field value is +// modified. Note that this function can overflow if multiplying any of the +// individual words exceeds a max uint32. In practice, this means the magnitude +// of the field must be a max of 8 to prevent overflow. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Square().Mul(f2) so that f = f^2 * f2. +// +// Preconditions: +// - The field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) Square() *FieldVal { + return f.SquareVal(f) +} + +// SquareVal squares the passed value and stores the result in f in constant +// time. Note that this function can overflow if multiplying any of the +// individual words exceeds a max uint32. In practice, this means the magnitude +// of the field being squared must be a max of 8 to prevent overflow. +// +// The field value is returned to support chaining. This enables syntax like: +// f3.SquareVal(f).Mul(f) so that f3 = f^2 * f = f^3. +// +// Preconditions: +// - The input field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) SquareVal(val *FieldVal) *FieldVal { + // This could be done with a couple of for loops and an array to store + // the intermediate terms, but this unrolled version is significantly + // faster. + + // Terms for 2^(fieldBase*0). + m := uint64(val.n[0]) * uint64(val.n[0]) + t0 := m & fieldBaseMask + + // Terms for 2^(fieldBase*1). + m = (m >> fieldBase) + 2*uint64(val.n[0])*uint64(val.n[1]) + t1 := m & fieldBaseMask + + // Terms for 2^(fieldBase*2). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[2]) + + uint64(val.n[1])*uint64(val.n[1]) + t2 := m & fieldBaseMask + + // Terms for 2^(fieldBase*3). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[3]) + + 2*uint64(val.n[1])*uint64(val.n[2]) + t3 := m & fieldBaseMask + + // Terms for 2^(fieldBase*4). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[4]) + + 2*uint64(val.n[1])*uint64(val.n[3]) + + uint64(val.n[2])*uint64(val.n[2]) + t4 := m & fieldBaseMask + + // Terms for 2^(fieldBase*5). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[5]) + + 2*uint64(val.n[1])*uint64(val.n[4]) + + 2*uint64(val.n[2])*uint64(val.n[3]) + t5 := m & fieldBaseMask + + // Terms for 2^(fieldBase*6). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[6]) + + 2*uint64(val.n[1])*uint64(val.n[5]) + + 2*uint64(val.n[2])*uint64(val.n[4]) + + uint64(val.n[3])*uint64(val.n[3]) + t6 := m & fieldBaseMask + + // Terms for 2^(fieldBase*7). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[7]) + + 2*uint64(val.n[1])*uint64(val.n[6]) + + 2*uint64(val.n[2])*uint64(val.n[5]) + + 2*uint64(val.n[3])*uint64(val.n[4]) + t7 := m & fieldBaseMask + + // Terms for 2^(fieldBase*8). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[8]) + + 2*uint64(val.n[1])*uint64(val.n[7]) + + 2*uint64(val.n[2])*uint64(val.n[6]) + + 2*uint64(val.n[3])*uint64(val.n[5]) + + uint64(val.n[4])*uint64(val.n[4]) + t8 := m & fieldBaseMask + + // Terms for 2^(fieldBase*9). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[9]) + + 2*uint64(val.n[1])*uint64(val.n[8]) + + 2*uint64(val.n[2])*uint64(val.n[7]) + + 2*uint64(val.n[3])*uint64(val.n[6]) + + 2*uint64(val.n[4])*uint64(val.n[5]) + t9 := m & fieldBaseMask + + // Terms for 2^(fieldBase*10). + m = (m >> fieldBase) + + 2*uint64(val.n[1])*uint64(val.n[9]) + + 2*uint64(val.n[2])*uint64(val.n[8]) + + 2*uint64(val.n[3])*uint64(val.n[7]) + + 2*uint64(val.n[4])*uint64(val.n[6]) + + uint64(val.n[5])*uint64(val.n[5]) + t10 := m & fieldBaseMask + + // Terms for 2^(fieldBase*11). + m = (m >> fieldBase) + + 2*uint64(val.n[2])*uint64(val.n[9]) + + 2*uint64(val.n[3])*uint64(val.n[8]) + + 2*uint64(val.n[4])*uint64(val.n[7]) + + 2*uint64(val.n[5])*uint64(val.n[6]) + t11 := m & fieldBaseMask + + // Terms for 2^(fieldBase*12). + m = (m >> fieldBase) + + 2*uint64(val.n[3])*uint64(val.n[9]) + + 2*uint64(val.n[4])*uint64(val.n[8]) + + 2*uint64(val.n[5])*uint64(val.n[7]) + + uint64(val.n[6])*uint64(val.n[6]) + t12 := m & fieldBaseMask + + // Terms for 2^(fieldBase*13). + m = (m >> fieldBase) + + 2*uint64(val.n[4])*uint64(val.n[9]) + + 2*uint64(val.n[5])*uint64(val.n[8]) + + 2*uint64(val.n[6])*uint64(val.n[7]) + t13 := m & fieldBaseMask + + // Terms for 2^(fieldBase*14). + m = (m >> fieldBase) + + 2*uint64(val.n[5])*uint64(val.n[9]) + + 2*uint64(val.n[6])*uint64(val.n[8]) + + uint64(val.n[7])*uint64(val.n[7]) + t14 := m & fieldBaseMask + + // Terms for 2^(fieldBase*15). + m = (m >> fieldBase) + + 2*uint64(val.n[6])*uint64(val.n[9]) + + 2*uint64(val.n[7])*uint64(val.n[8]) + t15 := m & fieldBaseMask + + // Terms for 2^(fieldBase*16). + m = (m >> fieldBase) + + 2*uint64(val.n[7])*uint64(val.n[9]) + + uint64(val.n[8])*uint64(val.n[8]) + t16 := m & fieldBaseMask + + // Terms for 2^(fieldBase*17). + m = (m >> fieldBase) + 2*uint64(val.n[8])*uint64(val.n[9]) + t17 := m & fieldBaseMask + + // Terms for 2^(fieldBase*18). + m = (m >> fieldBase) + uint64(val.n[9])*uint64(val.n[9]) + t18 := m & fieldBaseMask + + // What's left is for 2^(fieldBase*19). + t19 := m >> fieldBase + + // At this point, all of the terms are grouped into their respective + // base. + // + // Per [HAC] section 14.3.4: Reduction method of moduli of special form, + // when the modulus is of the special form m = b^t - c, highly efficient + // reduction can be achieved per the provided algorithm. + // + // The secp256k1 prime is equivalent to 2^256 - 4294968273, so it fits + // this criteria. + // + // 4294968273 in field representation (base 2^26) is: + // n[0] = 977 + // n[1] = 64 + // That is to say (2^26 * 64) + 977 = 4294968273 + // + // Since each word is in base 26, the upper terms (t10 and up) start + // at 260 bits (versus the final desired range of 256 bits), so the + // field representation of 'c' from above needs to be adjusted for the + // extra 4 bits by multiplying it by 2^4 = 16. 4294968273 * 16 = + // 68719492368. Thus, the adjusted field representation of 'c' is: + // n[0] = 977 * 16 = 15632 + // n[1] = 64 * 16 = 1024 + // That is to say (2^26 * 1024) + 15632 = 68719492368 + // + // To reduce the final term, t19, the entire 'c' value is needed instead + // of only n[0] because there are no more terms left to handle n[1]. + // This means there might be some magnitude left in the upper bits that + // is handled below. + m = t0 + t10*15632 + t0 = m & fieldBaseMask + m = (m >> fieldBase) + t1 + t10*1024 + t11*15632 + t1 = m & fieldBaseMask + m = (m >> fieldBase) + t2 + t11*1024 + t12*15632 + t2 = m & fieldBaseMask + m = (m >> fieldBase) + t3 + t12*1024 + t13*15632 + t3 = m & fieldBaseMask + m = (m >> fieldBase) + t4 + t13*1024 + t14*15632 + t4 = m & fieldBaseMask + m = (m >> fieldBase) + t5 + t14*1024 + t15*15632 + t5 = m & fieldBaseMask + m = (m >> fieldBase) + t6 + t15*1024 + t16*15632 + t6 = m & fieldBaseMask + m = (m >> fieldBase) + t7 + t16*1024 + t17*15632 + t7 = m & fieldBaseMask + m = (m >> fieldBase) + t8 + t17*1024 + t18*15632 + t8 = m & fieldBaseMask + m = (m >> fieldBase) + t9 + t18*1024 + t19*68719492368 + t9 = m & fieldMSBMask + m = m >> fieldMSBBits + + // At this point, if the magnitude is greater than 0, the overall value + // is greater than the max possible 256-bit value. In particular, it is + // "how many times larger" than the max value it is. + // + // The algorithm presented in [HAC] section 14.3.4 repeats until the + // quotient is zero. However, due to the above, we already know at + // least how many times we would need to repeat as it's the value + // currently in m. Thus we can simply multiply the magnitude by the + // field representation of the prime and do a single iteration. Notice + // that nothing will be changed when the magnitude is zero, so we could + // skip this in that case, however always running regardless allows it + // to run in constant time. The final result will be in the range + // 0 <= result <= prime + (2^64 - c), so it is guaranteed to have a + // magnitude of 1, but it is denormalized. + n := t0 + m*977 + f.n[0] = uint32(n & fieldBaseMask) + n = (n >> fieldBase) + t1 + m*64 + f.n[1] = uint32(n & fieldBaseMask) + f.n[2] = uint32((n >> fieldBase) + t2) + f.n[3] = uint32(t3) + f.n[4] = uint32(t4) + f.n[5] = uint32(t5) + f.n[6] = uint32(t6) + f.n[7] = uint32(t7) + f.n[8] = uint32(t8) + f.n[9] = uint32(t9) + + return f +} + +// Inverse finds the modular multiplicative inverse of the field value in +// constant time. The existing field value is modified. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Inverse().Mul(f2) so that f = f^-1 * f2. +// +// Preconditions: +// - The field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) Inverse() *FieldVal { + // Fermat's little theorem states that for a nonzero number a and prime + // prime p, a^(p-1) = 1 (mod p). Since the multiplicative inverse is + // a*b = 1 (mod p), it follows that b = a*a^(p-2) = a^(p-1) = 1 (mod p). + // Thus, a^(p-2) is the multiplicative inverse. + // + // In order to efficiently compute a^(p-2), p-2 needs to be split into + // a sequence of squares and multiplications that minimizes the number + // of multiplications needed (since they are more costly than + // squarings). Intermediate results are saved and reused as well. + // + // The secp256k1 prime - 2 is 2^256 - 4294968275. + // + // This has a cost of 258 field squarings and 33 field multiplications. + var a2, a3, a4, a10, a11, a21, a42, a45, a63, a1019, a1023 FieldVal + a2.SquareVal(f) + a3.Mul2(&a2, f) + a4.SquareVal(&a2) + a10.SquareVal(&a4).Mul(&a2) + a11.Mul2(&a10, f) + a21.Mul2(&a10, &a11) + a42.SquareVal(&a21) + a45.Mul2(&a42, &a3) + a63.Mul2(&a42, &a21) + a1019.SquareVal(&a63).Square().Square().Square().Mul(&a11) + a1023.Mul2(&a1019, &a4) + f.Set(&a63) // f = a^(2^6 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^11 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^16 - 1024) + f.Mul(&a1023) // f = a^(2^16 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^21 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^26 - 1024) + f.Mul(&a1023) // f = a^(2^26 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^31 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^36 - 1024) + f.Mul(&a1023) // f = a^(2^36 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^41 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^46 - 1024) + f.Mul(&a1023) // f = a^(2^46 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^51 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^56 - 1024) + f.Mul(&a1023) // f = a^(2^56 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^61 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^66 - 1024) + f.Mul(&a1023) // f = a^(2^66 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^71 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^76 - 1024) + f.Mul(&a1023) // f = a^(2^76 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^81 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^86 - 1024) + f.Mul(&a1023) // f = a^(2^86 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^91 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^96 - 1024) + f.Mul(&a1023) // f = a^(2^96 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^101 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^106 - 1024) + f.Mul(&a1023) // f = a^(2^106 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^111 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^116 - 1024) + f.Mul(&a1023) // f = a^(2^116 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^121 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^126 - 1024) + f.Mul(&a1023) // f = a^(2^126 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^131 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^136 - 1024) + f.Mul(&a1023) // f = a^(2^136 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^141 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^146 - 1024) + f.Mul(&a1023) // f = a^(2^146 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^151 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^156 - 1024) + f.Mul(&a1023) // f = a^(2^156 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^161 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^166 - 1024) + f.Mul(&a1023) // f = a^(2^166 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^171 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^176 - 1024) + f.Mul(&a1023) // f = a^(2^176 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^181 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^186 - 1024) + f.Mul(&a1023) // f = a^(2^186 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^191 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^196 - 1024) + f.Mul(&a1023) // f = a^(2^196 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^201 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^206 - 1024) + f.Mul(&a1023) // f = a^(2^206 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^211 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^216 - 1024) + f.Mul(&a1023) // f = a^(2^216 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^221 - 32) + f.Square().Square().Square().Square().Square() // f = a^(2^226 - 1024) + f.Mul(&a1019) // f = a^(2^226 - 5) + f.Square().Square().Square().Square().Square() // f = a^(2^231 - 160) + f.Square().Square().Square().Square().Square() // f = a^(2^236 - 5120) + f.Mul(&a1023) // f = a^(2^236 - 4097) + f.Square().Square().Square().Square().Square() // f = a^(2^241 - 131104) + f.Square().Square().Square().Square().Square() // f = a^(2^246 - 4195328) + f.Mul(&a1023) // f = a^(2^246 - 4194305) + f.Square().Square().Square().Square().Square() // f = a^(2^251 - 134217760) + f.Square().Square().Square().Square().Square() // f = a^(2^256 - 4294968320) + return f.Mul(&a45) // f = a^(2^256 - 4294968275) = a^(p-2) +} + +// IsGtOrEqPrimeMinusOrder returns whether or not the field value exceeds the +// group order divided by 2 in constant time. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsGtOrEqPrimeMinusOrder() bool { + // The secp256k1 prime is equivalent to 2^256 - 4294968273 and the group + // order is 2^256 - 432420386565659656852420866394968145599. Thus, + // the prime minus the group order is: + // 432420386565659656852420866390673177326 + // + // In hex that is: + // 0x00000000 00000000 00000000 00000001 45512319 50b75fc4 402da172 2fc9baee + // + // Converting that to field representation (base 2^26) is: + // + // n[0] = 0x03c9baee + // n[1] = 0x03685c8b + // n[2] = 0x01fc4402 + // n[3] = 0x006542dd + // n[4] = 0x01455123 + // + // This can be verified with the following test code: + // pMinusN := new(big.Int).Sub(curveParams.P, curveParams.N) + // var fv FieldVal + // fv.SetByteSlice(pMinusN.Bytes()) + // t.Logf("%x", fv.n) + // + // Outputs: [3c9baee 3685c8b 1fc4402 6542dd 1455123 0 0 0 0 0] + const ( + pMinusNWordZero = 0x03c9baee + pMinusNWordOne = 0x03685c8b + pMinusNWordTwo = 0x01fc4402 + pMinusNWordThree = 0x006542dd + pMinusNWordFour = 0x01455123 + pMinusNWordFive = 0x00000000 + pMinusNWordSix = 0x00000000 + pMinusNWordSeven = 0x00000000 + pMinusNWordEight = 0x00000000 + pMinusNWordNine = 0x00000000 + ) + + // The intuition here is that the value is greater than field prime minus + // the group order if one of the higher individual words is greater than the + // corresponding word and all higher words in the value are equal. + result := constantTimeGreater(f.n[9], pMinusNWordNine) + highWordsEqual := constantTimeEq(f.n[9], pMinusNWordNine) + result |= highWordsEqual & constantTimeGreater(f.n[8], pMinusNWordEight) + highWordsEqual &= constantTimeEq(f.n[8], pMinusNWordEight) + result |= highWordsEqual & constantTimeGreater(f.n[7], pMinusNWordSeven) + highWordsEqual &= constantTimeEq(f.n[7], pMinusNWordSeven) + result |= highWordsEqual & constantTimeGreater(f.n[6], pMinusNWordSix) + highWordsEqual &= constantTimeEq(f.n[6], pMinusNWordSix) + result |= highWordsEqual & constantTimeGreater(f.n[5], pMinusNWordFive) + highWordsEqual &= constantTimeEq(f.n[5], pMinusNWordFive) + result |= highWordsEqual & constantTimeGreater(f.n[4], pMinusNWordFour) + highWordsEqual &= constantTimeEq(f.n[4], pMinusNWordFour) + result |= highWordsEqual & constantTimeGreater(f.n[3], pMinusNWordThree) + highWordsEqual &= constantTimeEq(f.n[3], pMinusNWordThree) + result |= highWordsEqual & constantTimeGreater(f.n[2], pMinusNWordTwo) + highWordsEqual &= constantTimeEq(f.n[2], pMinusNWordTwo) + result |= highWordsEqual & constantTimeGreater(f.n[1], pMinusNWordOne) + highWordsEqual &= constantTimeEq(f.n[1], pMinusNWordOne) + result |= highWordsEqual & constantTimeGreaterOrEq(f.n[0], pMinusNWordZero) + + return result != 0 +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go new file mode 100644 index 000000000..91c3d3776 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go @@ -0,0 +1,91 @@ +// Copyright 2015 The btcsuite developers +// Copyright (c) 2015-2022 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + "compress/zlib" + "encoding/base64" + "io" + "strings" + "sync" +) + +//go:generate go run genprecomps.go + +// bytePointTable describes a table used to house pre-computed values for +// accelerating scalar base multiplication. +type bytePointTable [32][256]JacobianPoint + +// compressedBytePointsFn is set to a real function by the code generation to +// return the compressed pre-computed values for accelerating scalar base +// multiplication. +var compressedBytePointsFn func() string + +// s256BytePoints houses pre-computed values used to accelerate scalar base +// multiplication such that they are only loaded on first use. +var s256BytePoints = func() func() *bytePointTable { + // mustLoadBytePoints decompresses and deserializes the pre-computed byte + // points used to accelerate scalar base multiplication for the secp256k1 + // curve. + // + // This approach is used since it allows the compile to use significantly + // less ram and be performed much faster than it is with hard-coding the + // final in-memory data structure. At the same time, it is quite fast to + // generate the in-memory data structure on first use with this approach + // versus computing the table. + // + // It will panic on any errors because the data is hard coded and thus any + // errors means something is wrong in the source code. + var data *bytePointTable + mustLoadBytePoints := func() { + // There will be no byte points to load when generating them. + if compressedBytePointsFn == nil { + return + } + bp := compressedBytePointsFn() + + // Decompress the pre-computed table used to accelerate scalar base + // multiplication. + decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(bp)) + r, err := zlib.NewReader(decoder) + if err != nil { + panic(err) + } + serialized, err := io.ReadAll(r) + if err != nil { + panic(err) + } + + // Deserialize the precomputed byte points and set the memory table to + // them. + offset := 0 + var bytePoints bytePointTable + for byteNum := 0; byteNum < len(bytePoints); byteNum++ { + // All points in this window. + for i := 0; i < len(bytePoints[byteNum]); i++ { + p := &bytePoints[byteNum][i] + p.X.SetByteSlice(serialized[offset:]) + offset += 32 + p.Y.SetByteSlice(serialized[offset:]) + offset += 32 + p.Z.SetInt(1) + } + } + data = &bytePoints + } + + // Return a closure that initializes the data on first access. This is done + // because the table takes a non-trivial amount of memory and initializing + // it unconditionally would cause anything that imports the package, either + // directly, or indirectly via transitive deps, to use that memory even if + // the caller never accesses any parts of the package that actually needs + // access to it. + var loadBytePointsOnce sync.Once + return func() *bytePointTable { + loadBytePointsOnce.Do(mustLoadBytePoints) + return data + } +}() diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go new file mode 100644 index 000000000..f66496ed5 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go @@ -0,0 +1,1101 @@ +// Copyright (c) 2020-2022 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + "encoding/hex" + "math/big" +) + +// References: +// [SECG]: Recommended Elliptic Curve Domain Parameters +// https://www.secg.org/sec2-v2.pdf +// +// [HAC]: Handbook of Applied Cryptography Menezes, van Oorschot, Vanstone. +// http://cacr.uwaterloo.ca/hac/ + +// Many elliptic curve operations require working with scalars in a finite field +// characterized by the order of the group underlying the secp256k1 curve. +// Given this precision is larger than the biggest available native type, +// obviously some form of bignum math is needed. This code implements +// specialized fixed-precision field arithmetic rather than relying on an +// arbitrary-precision arithmetic package such as math/big for dealing with the +// math modulo the group order since the size is known. As a result, rather +// large performance gains are achieved by taking advantage of many +// optimizations not available to arbitrary-precision arithmetic and generic +// modular arithmetic algorithms. +// +// There are various ways to internally represent each element. For example, +// the most obvious representation would be to use an array of 4 uint64s (64 +// bits * 4 = 256 bits). However, that representation suffers from the fact +// that there is no native Go type large enough to handle the intermediate +// results while adding or multiplying two 64-bit numbers. +// +// Given the above, this implementation represents the field elements as 8 +// uint32s with each word (array entry) treated as base 2^32. This was chosen +// because most systems at the current time are 64-bit (or at least have 64-bit +// registers available for specialized purposes such as MMX) so the intermediate +// results can typically be done using a native register (and using uint64s to +// avoid the need for additional half-word arithmetic) + +const ( + // These fields provide convenient access to each of the words of the + // secp256k1 curve group order N to improve code readability. + // + // The group order of the curve per [SECG] is: + // 0xffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141 + orderWordZero uint32 = 0xd0364141 + orderWordOne uint32 = 0xbfd25e8c + orderWordTwo uint32 = 0xaf48a03b + orderWordThree uint32 = 0xbaaedce6 + orderWordFour uint32 = 0xfffffffe + orderWordFive uint32 = 0xffffffff + orderWordSix uint32 = 0xffffffff + orderWordSeven uint32 = 0xffffffff + + // These fields provide convenient access to each of the words of the two's + // complement of the secp256k1 curve group order N to improve code + // readability. + // + // The two's complement of the group order is: + // 0x00000000 00000000 00000000 00000001 45512319 50b75fc4 402da173 2fc9bebf + orderComplementWordZero uint32 = (^orderWordZero) + 1 + orderComplementWordOne uint32 = ^orderWordOne + orderComplementWordTwo uint32 = ^orderWordTwo + orderComplementWordThree uint32 = ^orderWordThree + //orderComplementWordFour uint32 = ^orderWordFour // unused + //orderComplementWordFive uint32 = ^orderWordFive // unused + //orderComplementWordSix uint32 = ^orderWordSix // unused + //orderComplementWordSeven uint32 = ^orderWordSeven // unused + + // These fields provide convenient access to each of the words of the + // secp256k1 curve group order N / 2 to improve code readability and avoid + // the need to recalculate them. + // + // The half order of the secp256k1 curve group is: + // 0x7fffffff ffffffff ffffffff ffffffff 5d576e73 57a4501d dfe92f46 681b20a0 + halfOrderWordZero uint32 = 0x681b20a0 + halfOrderWordOne uint32 = 0xdfe92f46 + halfOrderWordTwo uint32 = 0x57a4501d + halfOrderWordThree uint32 = 0x5d576e73 + halfOrderWordFour uint32 = 0xffffffff + halfOrderWordFive uint32 = 0xffffffff + halfOrderWordSix uint32 = 0xffffffff + halfOrderWordSeven uint32 = 0x7fffffff + + // uint32Mask is simply a mask with all bits set for a uint32 and is used to + // improve the readability of the code. + uint32Mask = 0xffffffff +) + +var ( + // zero32 is an array of 32 bytes used for the purposes of zeroing and is + // defined here to avoid extra allocations. + zero32 = [32]byte{} +) + +// ModNScalar implements optimized 256-bit constant-time fixed-precision +// arithmetic over the secp256k1 group order. This means all arithmetic is +// performed modulo: +// +// 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 +// +// It only implements the arithmetic needed for elliptic curve operations, +// however, the operations that are not implemented can typically be worked +// around if absolutely needed. For example, subtraction can be performed by +// adding the negation. +// +// Should it be absolutely necessary, conversion to the standard library +// math/big.Int can be accomplished by using the Bytes method, slicing the +// resulting fixed-size array, and feeding it to big.Int.SetBytes. However, +// that should typically be avoided when possible as conversion to big.Ints +// requires allocations, is not constant time, and is slower when working modulo +// the group order. +type ModNScalar struct { + // The scalar is represented as 8 32-bit integers in base 2^32. + // + // The following depicts the internal representation: + // --------------------------------------------------------- + // | n[7] | n[6] | ... | n[0] | + // | 32 bits | 32 bits | ... | 32 bits | + // | Mult: 2^(32*7) | Mult: 2^(32*6) | ... | Mult: 2^(32*0) | + // --------------------------------------------------------- + // + // For example, consider the number 2^87 + 2^42 + 1. It would be + // represented as: + // n[0] = 1 + // n[1] = 2^10 + // n[2] = 2^23 + // n[3..7] = 0 + // + // The full 256-bit value is then calculated by looping i from 7..0 and + // doing sum(n[i] * 2^(32i)) like so: + // n[7] * 2^(32*7) = 0 * 2^224 = 0 + // n[6] * 2^(32*6) = 0 * 2^192 = 0 + // ... + // n[2] * 2^(32*2) = 2^23 * 2^64 = 2^87 + // n[1] * 2^(32*1) = 2^10 * 2^32 = 2^42 + // n[0] * 2^(32*0) = 1 * 2^0 = 1 + // Sum: 0 + 0 + ... + 2^87 + 2^42 + 1 = 2^87 + 2^42 + 1 + n [8]uint32 +} + +// String returns the scalar as a human-readable hex string. +// +// This is NOT constant time. +func (s ModNScalar) String() string { + b := s.Bytes() + return hex.EncodeToString(b[:]) +} + +// Set sets the scalar equal to a copy of the passed one in constant time. +// +// The scalar is returned to support chaining. This enables syntax like: +// s := new(ModNScalar).Set(s2).Add(1) so that s = s2 + 1 where s2 is not +// modified. +func (s *ModNScalar) Set(val *ModNScalar) *ModNScalar { + *s = *val + return s +} + +// Zero sets the scalar to zero in constant time. A newly created scalar is +// already set to zero. This function can be useful to clear an existing scalar +// for reuse. +func (s *ModNScalar) Zero() { + s.n[0] = 0 + s.n[1] = 0 + s.n[2] = 0 + s.n[3] = 0 + s.n[4] = 0 + s.n[5] = 0 + s.n[6] = 0 + s.n[7] = 0 +} + +// IsZeroBit returns 1 when the scalar is equal to zero or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. See IsZero for the version that returns +// a bool. +func (s *ModNScalar) IsZeroBit() uint32 { + // The scalar can only be zero if no bits are set in any of the words. + bits := s.n[0] | s.n[1] | s.n[2] | s.n[3] | s.n[4] | s.n[5] | s.n[6] | s.n[7] + return constantTimeEq(bits, 0) +} + +// IsZero returns whether or not the scalar is equal to zero in constant time. +func (s *ModNScalar) IsZero() bool { + // The scalar can only be zero if no bits are set in any of the words. + bits := s.n[0] | s.n[1] | s.n[2] | s.n[3] | s.n[4] | s.n[5] | s.n[6] | s.n[7] + return bits == 0 +} + +// SetInt sets the scalar to the passed integer in constant time. This is a +// convenience function since it is fairly common to perform some arithmetic +// with small native integers. +// +// The scalar is returned to support chaining. This enables syntax like: +// s := new(ModNScalar).SetInt(2).Mul(s2) so that s = 2 * s2. +func (s *ModNScalar) SetInt(ui uint32) *ModNScalar { + s.Zero() + s.n[0] = ui + return s +} + +// constantTimeEq returns 1 if a == b or 0 otherwise in constant time. +func constantTimeEq(a, b uint32) uint32 { + return uint32((uint64(a^b) - 1) >> 63) +} + +// constantTimeNotEq returns 1 if a != b or 0 otherwise in constant time. +func constantTimeNotEq(a, b uint32) uint32 { + return ^uint32((uint64(a^b)-1)>>63) & 1 +} + +// constantTimeLess returns 1 if a < b or 0 otherwise in constant time. +func constantTimeLess(a, b uint32) uint32 { + return uint32((uint64(a) - uint64(b)) >> 63) +} + +// constantTimeLessOrEq returns 1 if a <= b or 0 otherwise in constant time. +func constantTimeLessOrEq(a, b uint32) uint32 { + return uint32((uint64(a) - uint64(b) - 1) >> 63) +} + +// constantTimeGreater returns 1 if a > b or 0 otherwise in constant time. +func constantTimeGreater(a, b uint32) uint32 { + return constantTimeLess(b, a) +} + +// constantTimeGreaterOrEq returns 1 if a >= b or 0 otherwise in constant time. +func constantTimeGreaterOrEq(a, b uint32) uint32 { + return constantTimeLessOrEq(b, a) +} + +// constantTimeMin returns min(a,b) in constant time. +func constantTimeMin(a, b uint32) uint32 { + return b ^ ((a ^ b) & -constantTimeLess(a, b)) +} + +// overflows determines if the current scalar is greater than or equal to the +// group order in constant time and returns 1 if it is or 0 otherwise. +func (s *ModNScalar) overflows() uint32 { + // The intuition here is that the scalar is greater than the group order if + // one of the higher individual words is greater than corresponding word of + // the group order and all higher words in the scalar are equal to their + // corresponding word of the group order. Since this type is modulo the + // group order, being equal is also an overflow back to 0. + // + // Note that the words 5, 6, and 7 are all the max uint32 value, so there is + // no need to test if those individual words of the scalar exceeds them, + // hence, only equality is checked for them. + highWordsEqual := constantTimeEq(s.n[7], orderWordSeven) + highWordsEqual &= constantTimeEq(s.n[6], orderWordSix) + highWordsEqual &= constantTimeEq(s.n[5], orderWordFive) + overflow := highWordsEqual & constantTimeGreater(s.n[4], orderWordFour) + highWordsEqual &= constantTimeEq(s.n[4], orderWordFour) + overflow |= highWordsEqual & constantTimeGreater(s.n[3], orderWordThree) + highWordsEqual &= constantTimeEq(s.n[3], orderWordThree) + overflow |= highWordsEqual & constantTimeGreater(s.n[2], orderWordTwo) + highWordsEqual &= constantTimeEq(s.n[2], orderWordTwo) + overflow |= highWordsEqual & constantTimeGreater(s.n[1], orderWordOne) + highWordsEqual &= constantTimeEq(s.n[1], orderWordOne) + overflow |= highWordsEqual & constantTimeGreaterOrEq(s.n[0], orderWordZero) + + return overflow +} + +// reduce256 reduces the current scalar modulo the group order in accordance +// with the overflows parameter in constant time. The overflows parameter +// specifies whether or not the scalar is known to be greater than the group +// order and MUST either be 1 in the case it is or 0 in the case it is not for a +// correct result. +func (s *ModNScalar) reduce256(overflows uint32) { + // Notice that since s < 2^256 < 2N (where N is the group order), the max + // possible number of reductions required is one. Therefore, in the case a + // reduction is needed, it can be performed with a single subtraction of N. + // Also, recall that subtraction is equivalent to addition by the two's + // complement while ignoring the carry. + // + // When s >= N, the overflows parameter will be 1. Conversely, it will be 0 + // when s < N. Thus multiplying by the overflows parameter will either + // result in 0 or the multiplicand itself. + // + // Combining the above along with the fact that s + 0 = s, the following is + // a constant time implementation that works by either adding 0 or the two's + // complement of N as needed. + // + // The final result will be in the range 0 <= s < N as expected. + overflows64 := uint64(overflows) + c := uint64(s.n[0]) + overflows64*uint64(orderComplementWordZero) + s.n[0] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[1]) + overflows64*uint64(orderComplementWordOne) + s.n[1] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[2]) + overflows64*uint64(orderComplementWordTwo) + s.n[2] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[3]) + overflows64*uint64(orderComplementWordThree) + s.n[3] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[4]) + overflows64 // * 1 + s.n[4] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[5]) // + overflows64 * 0 + s.n[5] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[6]) // + overflows64 * 0 + s.n[6] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[7]) // + overflows64 * 0 + s.n[7] = uint32(c & uint32Mask) +} + +// SetBytes interprets the provided array as a 256-bit big-endian unsigned +// integer, reduces it modulo the group order, sets the scalar to the result, +// and returns either 1 if it was reduced (aka it overflowed) or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. +func (s *ModNScalar) SetBytes(b *[32]byte) uint32 { + // Pack the 256 total bits across the 8 uint32 words. This could be done + // with a for loop, but benchmarks show this unrolled version is about 2 + // times faster than the variant that uses a loop. + s.n[0] = uint32(b[31]) | uint32(b[30])<<8 | uint32(b[29])<<16 | uint32(b[28])<<24 + s.n[1] = uint32(b[27]) | uint32(b[26])<<8 | uint32(b[25])<<16 | uint32(b[24])<<24 + s.n[2] = uint32(b[23]) | uint32(b[22])<<8 | uint32(b[21])<<16 | uint32(b[20])<<24 + s.n[3] = uint32(b[19]) | uint32(b[18])<<8 | uint32(b[17])<<16 | uint32(b[16])<<24 + s.n[4] = uint32(b[15]) | uint32(b[14])<<8 | uint32(b[13])<<16 | uint32(b[12])<<24 + s.n[5] = uint32(b[11]) | uint32(b[10])<<8 | uint32(b[9])<<16 | uint32(b[8])<<24 + s.n[6] = uint32(b[7]) | uint32(b[6])<<8 | uint32(b[5])<<16 | uint32(b[4])<<24 + s.n[7] = uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 + + // The value might be >= N, so reduce it as required and return whether or + // not it was reduced. + needsReduce := s.overflows() + s.reduce256(needsReduce) + return needsReduce +} + +// zeroArray32 zeroes the provided 32-byte buffer. +func zeroArray32(b *[32]byte) { + copy(b[:], zero32[:]) +} + +// SetByteSlice interprets the provided slice as a 256-bit big-endian unsigned +// integer (meaning it is truncated to the first 32 bytes), reduces it modulo +// the group order, sets the scalar to the result, and returns whether or not +// the resulting truncated 256-bit integer overflowed in constant time. +// +// Note that since passing a slice with more than 32 bytes is truncated, it is +// possible that the truncated value is less than the order of the curve and +// hence it will not be reported as having overflowed in that case. It is up to +// the caller to decide whether it needs to provide numbers of the appropriate +// size or it is acceptable to use this function with the described truncation +// and overflow behavior. +func (s *ModNScalar) SetByteSlice(b []byte) bool { + var b32 [32]byte + b = b[:constantTimeMin(uint32(len(b)), 32)] + copy(b32[:], b32[:32-len(b)]) + copy(b32[32-len(b):], b) + result := s.SetBytes(&b32) + zeroArray32(&b32) + return result != 0 +} + +// PutBytesUnchecked unpacks the scalar to a 32-byte big-endian value directly +// into the passed byte slice in constant time. The target slice must must have +// at least 32 bytes available or it will panic. +// +// There is a similar function, PutBytes, which unpacks the scalar into a +// 32-byte array directly. This version is provided since it can be useful to +// write directly into part of a larger buffer without needing a separate +// allocation. +// +// Preconditions: +// - The target slice MUST have at least 32 bytes available +func (s *ModNScalar) PutBytesUnchecked(b []byte) { + // Unpack the 256 total bits from the 8 uint32 words. This could be done + // with a for loop, but benchmarks show this unrolled version is about 2 + // times faster than the variant which uses a loop. + b[31] = byte(s.n[0]) + b[30] = byte(s.n[0] >> 8) + b[29] = byte(s.n[0] >> 16) + b[28] = byte(s.n[0] >> 24) + b[27] = byte(s.n[1]) + b[26] = byte(s.n[1] >> 8) + b[25] = byte(s.n[1] >> 16) + b[24] = byte(s.n[1] >> 24) + b[23] = byte(s.n[2]) + b[22] = byte(s.n[2] >> 8) + b[21] = byte(s.n[2] >> 16) + b[20] = byte(s.n[2] >> 24) + b[19] = byte(s.n[3]) + b[18] = byte(s.n[3] >> 8) + b[17] = byte(s.n[3] >> 16) + b[16] = byte(s.n[3] >> 24) + b[15] = byte(s.n[4]) + b[14] = byte(s.n[4] >> 8) + b[13] = byte(s.n[4] >> 16) + b[12] = byte(s.n[4] >> 24) + b[11] = byte(s.n[5]) + b[10] = byte(s.n[5] >> 8) + b[9] = byte(s.n[5] >> 16) + b[8] = byte(s.n[5] >> 24) + b[7] = byte(s.n[6]) + b[6] = byte(s.n[6] >> 8) + b[5] = byte(s.n[6] >> 16) + b[4] = byte(s.n[6] >> 24) + b[3] = byte(s.n[7]) + b[2] = byte(s.n[7] >> 8) + b[1] = byte(s.n[7] >> 16) + b[0] = byte(s.n[7] >> 24) +} + +// PutBytes unpacks the scalar to a 32-byte big-endian value using the passed +// byte array in constant time. +// +// There is a similar function, PutBytesUnchecked, which unpacks the scalar into +// a slice that must have at least 32 bytes available. This version is provided +// since it can be useful to write directly into an array that is type checked. +// +// Alternatively, there is also Bytes, which unpacks the scalar into a new array +// and returns that which can sometimes be more ergonomic in applications that +// aren't concerned about an additional copy. +func (s *ModNScalar) PutBytes(b *[32]byte) { + s.PutBytesUnchecked(b[:]) +} + +// Bytes unpacks the scalar to a 32-byte big-endian value in constant time. +// +// See PutBytes and PutBytesUnchecked for variants that allow an array or slice +// to be passed which can be useful to cut down on the number of allocations +// by allowing the caller to reuse a buffer or write directly into part of a +// larger buffer. +func (s *ModNScalar) Bytes() [32]byte { + var b [32]byte + s.PutBytesUnchecked(b[:]) + return b +} + +// IsOdd returns whether or not the scalar is an odd number in constant time. +func (s *ModNScalar) IsOdd() bool { + // Only odd numbers have the bottom bit set. + return s.n[0]&1 == 1 +} + +// Equals returns whether or not the two scalars are the same in constant time. +func (s *ModNScalar) Equals(val *ModNScalar) bool { + // Xor only sets bits when they are different, so the two scalars can only + // be the same if no bits are set after xoring each word. + bits := (s.n[0] ^ val.n[0]) | (s.n[1] ^ val.n[1]) | (s.n[2] ^ val.n[2]) | + (s.n[3] ^ val.n[3]) | (s.n[4] ^ val.n[4]) | (s.n[5] ^ val.n[5]) | + (s.n[6] ^ val.n[6]) | (s.n[7] ^ val.n[7]) + + return bits == 0 +} + +// Add2 adds the passed two scalars together modulo the group order in constant +// time and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s3.Add2(s, s2).AddInt(1) so that s3 = s + s2 + 1. +func (s *ModNScalar) Add2(val1, val2 *ModNScalar) *ModNScalar { + c := uint64(val1.n[0]) + uint64(val2.n[0]) + s.n[0] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[1]) + uint64(val2.n[1]) + s.n[1] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[2]) + uint64(val2.n[2]) + s.n[2] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[3]) + uint64(val2.n[3]) + s.n[3] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[4]) + uint64(val2.n[4]) + s.n[4] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[5]) + uint64(val2.n[5]) + s.n[5] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[6]) + uint64(val2.n[6]) + s.n[6] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[7]) + uint64(val2.n[7]) + s.n[7] = uint32(c & uint32Mask) + + // The result is now 256 bits, but it might still be >= N, so use the + // existing normal reduce method for 256-bit values. + s.reduce256(uint32(c>>32) + s.overflows()) + return s +} + +// Add adds the passed scalar to the existing one modulo the group order in +// constant time and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Add(s2).AddInt(1) so that s = s + s2 + 1. +func (s *ModNScalar) Add(val *ModNScalar) *ModNScalar { + return s.Add2(s, val) +} + +// accumulator96 provides a 96-bit accumulator for use in the intermediate +// calculations requiring more than 64-bits. +type accumulator96 struct { + n [3]uint32 +} + +// Add adds the passed unsigned 64-bit value to the accumulator. +func (a *accumulator96) Add(v uint64) { + low := uint32(v & uint32Mask) + hi := uint32(v >> 32) + a.n[0] += low + hi += constantTimeLess(a.n[0], low) // Carry if overflow in n[0]. + a.n[1] += hi + a.n[2] += constantTimeLess(a.n[1], hi) // Carry if overflow in n[1]. +} + +// Rsh32 right shifts the accumulator by 32 bits. +func (a *accumulator96) Rsh32() { + a.n[0] = a.n[1] + a.n[1] = a.n[2] + a.n[2] = 0 +} + +// reduce385 reduces the 385-bit intermediate result in the passed terms modulo +// the group order in constant time and stores the result in s. +func (s *ModNScalar) reduce385(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12 uint64) { + // At this point, the intermediate result in the passed terms has been + // reduced to fit within 385 bits, so reduce it again using the same method + // described in reduce512. As before, the intermediate result will end up + // being reduced by another 127 bits to 258 bits, thus 9 32-bit terms are + // needed for this iteration. The reduced terms are assigned back to t0 + // through t8. + // + // Note that several of the intermediate calculations require adding 64-bit + // products together which would overflow a uint64, so a 96-bit accumulator + // is used instead until the value is reduced enough to use native uint64s. + + // Terms for 2^(32*0). + var acc accumulator96 + acc.n[0] = uint32(t0) // == acc.Add(t0) because acc is guaranteed to be 0. + acc.Add(t8 * uint64(orderComplementWordZero)) + t0 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*1). + acc.Add(t1) + acc.Add(t8 * uint64(orderComplementWordOne)) + acc.Add(t9 * uint64(orderComplementWordZero)) + t1 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*2). + acc.Add(t2) + acc.Add(t8 * uint64(orderComplementWordTwo)) + acc.Add(t9 * uint64(orderComplementWordOne)) + acc.Add(t10 * uint64(orderComplementWordZero)) + t2 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*3). + acc.Add(t3) + acc.Add(t8 * uint64(orderComplementWordThree)) + acc.Add(t9 * uint64(orderComplementWordTwo)) + acc.Add(t10 * uint64(orderComplementWordOne)) + acc.Add(t11 * uint64(orderComplementWordZero)) + t3 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*4). + acc.Add(t4) + acc.Add(t8) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t9 * uint64(orderComplementWordThree)) + acc.Add(t10 * uint64(orderComplementWordTwo)) + acc.Add(t11 * uint64(orderComplementWordOne)) + acc.Add(t12 * uint64(orderComplementWordZero)) + t4 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*5). + acc.Add(t5) + // acc.Add(t8 * uint64(orderComplementWordFive)) // 0 + acc.Add(t9) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t10 * uint64(orderComplementWordThree)) + acc.Add(t11 * uint64(orderComplementWordTwo)) + acc.Add(t12 * uint64(orderComplementWordOne)) + t5 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*6). + acc.Add(t6) + // acc.Add(t8 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t9 * uint64(orderComplementWordFive)) // 0 + acc.Add(t10) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t11 * uint64(orderComplementWordThree)) + acc.Add(t12 * uint64(orderComplementWordTwo)) + t6 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*7). + acc.Add(t7) + // acc.Add(t8 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t9 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t10 * uint64(orderComplementWordFive)) // 0 + acc.Add(t11) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t12 * uint64(orderComplementWordThree)) + t7 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*8). + // acc.Add(t9 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t10 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t11 * uint64(orderComplementWordFive)) // 0 + acc.Add(t12) // * uint64(orderComplementWordFour) // * 1 + t8 = uint64(acc.n[0]) + // acc.Rsh32() // No need since not used after this. Guaranteed to be 0. + + // NOTE: All of the remaining multiplications for this iteration result in 0 + // as they all involve multiplying by combinations of the fifth, sixth, and + // seventh words of the two's complement of N, which are 0, so skip them. + + // At this point, the result is reduced to fit within 258 bits, so reduce it + // again using a slightly modified version of the same method. The maximum + // value in t8 is 2 at this point and therefore multiplying it by each word + // of the two's complement of N and adding it to a 32-bit term will result + // in a maximum requirement of 33 bits, so it is safe to use native uint64s + // here for the intermediate term carry propagation. + // + // Also, since the maximum value in t8 is 2, this ends up reducing by + // another 2 bits to 256 bits. + c := t0 + t8*uint64(orderComplementWordZero) + s.n[0] = uint32(c & uint32Mask) + c = (c >> 32) + t1 + t8*uint64(orderComplementWordOne) + s.n[1] = uint32(c & uint32Mask) + c = (c >> 32) + t2 + t8*uint64(orderComplementWordTwo) + s.n[2] = uint32(c & uint32Mask) + c = (c >> 32) + t3 + t8*uint64(orderComplementWordThree) + s.n[3] = uint32(c & uint32Mask) + c = (c >> 32) + t4 + t8 // * uint64(orderComplementWordFour) == * 1 + s.n[4] = uint32(c & uint32Mask) + c = (c >> 32) + t5 // + t8*uint64(orderComplementWordFive) == 0 + s.n[5] = uint32(c & uint32Mask) + c = (c >> 32) + t6 // + t8*uint64(orderComplementWordSix) == 0 + s.n[6] = uint32(c & uint32Mask) + c = (c >> 32) + t7 // + t8*uint64(orderComplementWordSeven) == 0 + s.n[7] = uint32(c & uint32Mask) + + // The result is now 256 bits, but it might still be >= N, so use the + // existing normal reduce method for 256-bit values. + s.reduce256(uint32(c>>32) + s.overflows()) +} + +// reduce512 reduces the 512-bit intermediate result in the passed terms modulo +// the group order down to 385 bits in constant time and stores the result in s. +func (s *ModNScalar) reduce512(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15 uint64) { + // At this point, the intermediate result in the passed terms is grouped + // into the respective bases. + // + // Per [HAC] section 14.3.4: Reduction method of moduli of special form, + // when the modulus is of the special form m = b^t - c, where log_2(c) < t, + // highly efficient reduction can be achieved per the provided algorithm. + // + // The secp256k1 group order fits this criteria since it is: + // 2^256 - 432420386565659656852420866394968145599 + // + // Technically the max possible value here is (N-1)^2 since the two scalars + // being multiplied are always mod N. Nevertheless, it is safer to consider + // it to be (2^256-1)^2 = 2^512 - 2^256 + 1 since it is the product of two + // 256-bit values. + // + // The algorithm is to reduce the result modulo the prime by subtracting + // multiples of the group order N. However, in order simplify carry + // propagation, this adds with the two's complement of N to achieve the same + // result. + // + // Since the two's complement of N has 127 leading zero bits, this will end + // up reducing the intermediate result from 512 bits to 385 bits, resulting + // in 13 32-bit terms. The reduced terms are assigned back to t0 through + // t12. + // + // Note that several of the intermediate calculations require adding 64-bit + // products together which would overflow a uint64, so a 96-bit accumulator + // is used instead. + + // Terms for 2^(32*0). + var acc accumulator96 + acc.n[0] = uint32(t0) // == acc.Add(t0) because acc is guaranteed to be 0. + acc.Add(t8 * uint64(orderComplementWordZero)) + t0 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*1). + acc.Add(t1) + acc.Add(t8 * uint64(orderComplementWordOne)) + acc.Add(t9 * uint64(orderComplementWordZero)) + t1 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*2). + acc.Add(t2) + acc.Add(t8 * uint64(orderComplementWordTwo)) + acc.Add(t9 * uint64(orderComplementWordOne)) + acc.Add(t10 * uint64(orderComplementWordZero)) + t2 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*3). + acc.Add(t3) + acc.Add(t8 * uint64(orderComplementWordThree)) + acc.Add(t9 * uint64(orderComplementWordTwo)) + acc.Add(t10 * uint64(orderComplementWordOne)) + acc.Add(t11 * uint64(orderComplementWordZero)) + t3 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*4). + acc.Add(t4) + acc.Add(t8) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t9 * uint64(orderComplementWordThree)) + acc.Add(t10 * uint64(orderComplementWordTwo)) + acc.Add(t11 * uint64(orderComplementWordOne)) + acc.Add(t12 * uint64(orderComplementWordZero)) + t4 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*5). + acc.Add(t5) + // acc.Add(t8 * uint64(orderComplementWordFive)) // 0 + acc.Add(t9) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t10 * uint64(orderComplementWordThree)) + acc.Add(t11 * uint64(orderComplementWordTwo)) + acc.Add(t12 * uint64(orderComplementWordOne)) + acc.Add(t13 * uint64(orderComplementWordZero)) + t5 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*6). + acc.Add(t6) + // acc.Add(t8 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t9 * uint64(orderComplementWordFive)) // 0 + acc.Add(t10) // * uint64(orderComplementWordFour)) // * 1 + acc.Add(t11 * uint64(orderComplementWordThree)) + acc.Add(t12 * uint64(orderComplementWordTwo)) + acc.Add(t13 * uint64(orderComplementWordOne)) + acc.Add(t14 * uint64(orderComplementWordZero)) + t6 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*7). + acc.Add(t7) + // acc.Add(t8 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t9 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t10 * uint64(orderComplementWordFive)) // 0 + acc.Add(t11) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t12 * uint64(orderComplementWordThree)) + acc.Add(t13 * uint64(orderComplementWordTwo)) + acc.Add(t14 * uint64(orderComplementWordOne)) + acc.Add(t15 * uint64(orderComplementWordZero)) + t7 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*8). + // acc.Add(t9 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t10 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t11 * uint64(orderComplementWordFive)) // 0 + acc.Add(t12) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t13 * uint64(orderComplementWordThree)) + acc.Add(t14 * uint64(orderComplementWordTwo)) + acc.Add(t15 * uint64(orderComplementWordOne)) + t8 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*9). + // acc.Add(t10 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t11 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t12 * uint64(orderComplementWordFive)) // 0 + acc.Add(t13) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t14 * uint64(orderComplementWordThree)) + acc.Add(t15 * uint64(orderComplementWordTwo)) + t9 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*10). + // acc.Add(t11 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t12 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t13 * uint64(orderComplementWordFive)) // 0 + acc.Add(t14) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t15 * uint64(orderComplementWordThree)) + t10 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*11). + // acc.Add(t12 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t13 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t14 * uint64(orderComplementWordFive)) // 0 + acc.Add(t15) // * uint64(orderComplementWordFour) // * 1 + t11 = uint64(acc.n[0]) + acc.Rsh32() + + // NOTE: All of the remaining multiplications for this iteration result in 0 + // as they all involve multiplying by combinations of the fifth, sixth, and + // seventh words of the two's complement of N, which are 0, so skip them. + + // Terms for 2^(32*12). + t12 = uint64(acc.n[0]) + // acc.Rsh32() // No need since not used after this. Guaranteed to be 0. + + // At this point, the result is reduced to fit within 385 bits, so reduce it + // again using the same method accordingly. + s.reduce385(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12) +} + +// Mul2 multiplies the passed two scalars together modulo the group order in +// constant time and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s3.Mul2(s, s2).AddInt(1) so that s3 = (s * s2) + 1. +func (s *ModNScalar) Mul2(val, val2 *ModNScalar) *ModNScalar { + // This could be done with for loops and an array to store the intermediate + // terms, but this unrolled version is significantly faster. + + // The overall strategy employed here is: + // 1) Calculate the 512-bit product of the two scalars using the standard + // pencil-and-paper method. + // 2) Reduce the result modulo the prime by effectively subtracting + // multiples of the group order N (actually performed by adding multiples + // of the two's complement of N to avoid implementing subtraction). + // 3) Repeat step 2 noting that each iteration reduces the required number + // of bits by 127 because the two's complement of N has 127 leading zero + // bits. + // 4) Once reduced to 256 bits, call the existing reduce method to perform + // a final reduction as needed. + // + // Note that several of the intermediate calculations require adding 64-bit + // products together which would overflow a uint64, so a 96-bit accumulator + // is used instead. + + // Terms for 2^(32*0). + var acc accumulator96 + acc.Add(uint64(val.n[0]) * uint64(val2.n[0])) + t0 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*1). + acc.Add(uint64(val.n[0]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[0])) + t1 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*2). + acc.Add(uint64(val.n[0]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[0])) + t2 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*3). + acc.Add(uint64(val.n[0]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[0])) + t3 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*4). + acc.Add(uint64(val.n[0]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[0])) + t4 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*5). + acc.Add(uint64(val.n[0]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[0])) + t5 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*6). + acc.Add(uint64(val.n[0]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[0])) + t6 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*7). + acc.Add(uint64(val.n[0]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[0])) + t7 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*8). + acc.Add(uint64(val.n[1]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[1])) + t8 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*9). + acc.Add(uint64(val.n[2]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[2])) + t9 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*10). + acc.Add(uint64(val.n[3]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[3])) + t10 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*11). + acc.Add(uint64(val.n[4]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[4])) + t11 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*12). + acc.Add(uint64(val.n[5]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[5])) + t12 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*13). + acc.Add(uint64(val.n[6]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[6])) + t13 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*14). + acc.Add(uint64(val.n[7]) * uint64(val2.n[7])) + t14 := uint64(acc.n[0]) + acc.Rsh32() + + // What's left is for 2^(32*15). + t15 := uint64(acc.n[0]) + // acc.Rsh32() // No need since not used after this. Guaranteed to be 0. + + // At this point, all of the terms are grouped into their respective base + // and occupy up to 512 bits. Reduce the result accordingly. + s.reduce512(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, + t15) + return s +} + +// Mul multiplies the passed scalar with the existing one modulo the group order +// in constant time and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Mul(s2).AddInt(1) so that s = (s * s2) + 1. +func (s *ModNScalar) Mul(val *ModNScalar) *ModNScalar { + return s.Mul2(s, val) +} + +// SquareVal squares the passed scalar modulo the group order in constant time +// and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s3.SquareVal(s).Mul(s) so that s3 = s^2 * s = s^3. +func (s *ModNScalar) SquareVal(val *ModNScalar) *ModNScalar { + // This could technically be optimized slightly to take advantage of the + // fact that many of the intermediate calculations in squaring are just + // doubling, however, benchmarking has shown that due to the need to use a + // 96-bit accumulator, any savings are essentially offset by that and + // consequently there is no real difference in performance over just + // multiplying the value by itself to justify the extra code for now. This + // can be revisited in the future if it becomes a bottleneck in practice. + + return s.Mul2(val, val) +} + +// Square squares the scalar modulo the group order in constant time. The +// existing scalar is modified. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Square().Mul(s2) so that s = s^2 * s2. +func (s *ModNScalar) Square() *ModNScalar { + return s.SquareVal(s) +} + +// NegateVal negates the passed scalar modulo the group order and stores the +// result in s in constant time. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.NegateVal(s2).AddInt(1) so that s = -s2 + 1. +func (s *ModNScalar) NegateVal(val *ModNScalar) *ModNScalar { + // Since the scalar is already in the range 0 <= val < N, where N is the + // group order, negation modulo the group order is just the group order + // minus the value. This implies that the result will always be in the + // desired range with the sole exception of 0 because N - 0 = N itself. + // + // Therefore, in order to avoid the need to reduce the result for every + // other case in order to achieve constant time, this creates a mask that is + // all 0s in the case of the scalar being negated is 0 and all 1s otherwise + // and bitwise ands that mask with each word. + // + // Finally, to simplify the carry propagation, this adds the two's + // complement of the scalar to N in order to achieve the same result. + bits := val.n[0] | val.n[1] | val.n[2] | val.n[3] | val.n[4] | val.n[5] | + val.n[6] | val.n[7] + mask := uint64(uint32Mask * constantTimeNotEq(bits, 0)) + c := uint64(orderWordZero) + (uint64(^val.n[0]) + 1) + s.n[0] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordOne) + uint64(^val.n[1]) + s.n[1] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordTwo) + uint64(^val.n[2]) + s.n[2] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordThree) + uint64(^val.n[3]) + s.n[3] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordFour) + uint64(^val.n[4]) + s.n[4] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordFive) + uint64(^val.n[5]) + s.n[5] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordSix) + uint64(^val.n[6]) + s.n[6] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordSeven) + uint64(^val.n[7]) + s.n[7] = uint32(c & mask) + return s +} + +// Negate negates the scalar modulo the group order in constant time. The +// existing scalar is modified. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Negate().AddInt(1) so that s = -s + 1. +func (s *ModNScalar) Negate() *ModNScalar { + return s.NegateVal(s) +} + +// InverseValNonConst finds the modular multiplicative inverse of the passed +// scalar and stores result in s in *non-constant* time. +// +// The scalar is returned to support chaining. This enables syntax like: +// s3.InverseVal(s1).Mul(s2) so that s3 = s1^-1 * s2. +func (s *ModNScalar) InverseValNonConst(val *ModNScalar) *ModNScalar { + // This is making use of big integers for now. Ideally it will be replaced + // with an implementation that does not depend on big integers. + valBytes := val.Bytes() + bigVal := new(big.Int).SetBytes(valBytes[:]) + bigVal.ModInverse(bigVal, curveParams.N) + s.SetByteSlice(bigVal.Bytes()) + return s +} + +// InverseNonConst finds the modular multiplicative inverse of the scalar in +// *non-constant* time. The existing scalar is modified. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Inverse().Mul(s2) so that s = s^-1 * s2. +func (s *ModNScalar) InverseNonConst() *ModNScalar { + return s.InverseValNonConst(s) +} + +// IsOverHalfOrder returns whether or not the scalar exceeds the group order +// divided by 2 in constant time. +func (s *ModNScalar) IsOverHalfOrder() bool { + // The intuition here is that the scalar is greater than half of the group + // order if one of the higher individual words is greater than the + // corresponding word of the half group order and all higher words in the + // scalar are equal to their corresponding word of the half group order. + // + // Note that the words 4, 5, and 6 are all the max uint32 value, so there is + // no need to test if those individual words of the scalar exceeds them, + // hence, only equality is checked for them. + result := constantTimeGreater(s.n[7], halfOrderWordSeven) + highWordsEqual := constantTimeEq(s.n[7], halfOrderWordSeven) + highWordsEqual &= constantTimeEq(s.n[6], halfOrderWordSix) + highWordsEqual &= constantTimeEq(s.n[5], halfOrderWordFive) + highWordsEqual &= constantTimeEq(s.n[4], halfOrderWordFour) + result |= highWordsEqual & constantTimeGreater(s.n[3], halfOrderWordThree) + highWordsEqual &= constantTimeEq(s.n[3], halfOrderWordThree) + result |= highWordsEqual & constantTimeGreater(s.n[2], halfOrderWordTwo) + highWordsEqual &= constantTimeEq(s.n[2], halfOrderWordTwo) + result |= highWordsEqual & constantTimeGreater(s.n[1], halfOrderWordOne) + highWordsEqual &= constantTimeEq(s.n[1], halfOrderWordOne) + result |= highWordsEqual & constantTimeGreater(s.n[0], halfOrderWordZero) + + return result != 0 +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go new file mode 100644 index 000000000..81b205d9c --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go @@ -0,0 +1,263 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2020 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + "bytes" + "crypto/sha256" + "hash" +) + +// References: +// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone) +// +// [ISO/IEC 8825-1]: Information technology — ASN.1 encoding rules: +// Specification of Basic Encoding Rules (BER), Canonical Encoding Rules +// (CER) and Distinguished Encoding Rules (DER) +// +// [SEC1]: Elliptic Curve Cryptography (May 31, 2009, Version 2.0) +// https://www.secg.org/sec1-v2.pdf + +var ( + // singleZero is used during RFC6979 nonce generation. It is provided + // here to avoid the need to create it multiple times. + singleZero = []byte{0x00} + + // zeroInitializer is used during RFC6979 nonce generation. It is provided + // here to avoid the need to create it multiple times. + zeroInitializer = bytes.Repeat([]byte{0x00}, sha256.BlockSize) + + // singleOne is used during RFC6979 nonce generation. It is provided + // here to avoid the need to create it multiple times. + singleOne = []byte{0x01} + + // oneInitializer is used during RFC6979 nonce generation. It is provided + // here to avoid the need to create it multiple times. + oneInitializer = bytes.Repeat([]byte{0x01}, sha256.Size) +) + +// hmacsha256 implements a resettable version of HMAC-SHA256. +type hmacsha256 struct { + inner, outer hash.Hash + ipad, opad [sha256.BlockSize]byte +} + +// Write adds data to the running hash. +func (h *hmacsha256) Write(p []byte) { + h.inner.Write(p) +} + +// initKey initializes the HMAC-SHA256 instance to the provided key. +func (h *hmacsha256) initKey(key []byte) { + // Hash the key if it is too large. + if len(key) > sha256.BlockSize { + h.outer.Write(key) + key = h.outer.Sum(nil) + } + copy(h.ipad[:], key) + copy(h.opad[:], key) + for i := range h.ipad { + h.ipad[i] ^= 0x36 + } + for i := range h.opad { + h.opad[i] ^= 0x5c + } + h.inner.Write(h.ipad[:]) +} + +// ResetKey resets the HMAC-SHA256 to its initial state and then initializes it +// with the provided key. It is equivalent to creating a new instance with the +// provided key without allocating more memory. +func (h *hmacsha256) ResetKey(key []byte) { + h.inner.Reset() + h.outer.Reset() + copy(h.ipad[:], zeroInitializer) + copy(h.opad[:], zeroInitializer) + h.initKey(key) +} + +// Resets the HMAC-SHA256 to its initial state using the current key. +func (h *hmacsha256) Reset() { + h.inner.Reset() + h.inner.Write(h.ipad[:]) +} + +// Sum returns the hash of the written data. +func (h *hmacsha256) Sum() []byte { + h.outer.Reset() + h.outer.Write(h.opad[:]) + h.outer.Write(h.inner.Sum(nil)) + return h.outer.Sum(nil) +} + +// newHMACSHA256 returns a new HMAC-SHA256 hasher using the provided key. +func newHMACSHA256(key []byte) *hmacsha256 { + h := new(hmacsha256) + h.inner = sha256.New() + h.outer = sha256.New() + h.initKey(key) + return h +} + +// NonceRFC6979 generates a nonce deterministically according to RFC 6979 using +// HMAC-SHA256 for the hashing function. It takes a 32-byte hash as an input +// and returns a 32-byte nonce to be used for deterministic signing. The extra +// and version arguments are optional, but allow additional data to be added to +// the input of the HMAC. When provided, the extra data must be 32-bytes and +// version must be 16 bytes or they will be ignored. +// +// Finally, the extraIterations parameter provides a method to produce a stream +// of deterministic nonces to ensure the signing code is able to produce a nonce +// that results in a valid signature in the extremely unlikely event the +// original nonce produced results in an invalid signature (e.g. R == 0). +// Signing code should start with 0 and increment it if necessary. +func NonceRFC6979(privKey []byte, hash []byte, extra []byte, version []byte, extraIterations uint32) *ModNScalar { + // Input to HMAC is the 32-byte private key and the 32-byte hash. In + // addition, it may include the optional 32-byte extra data and 16-byte + // version. Create a fixed-size array to avoid extra allocs and slice it + // properly. + const ( + privKeyLen = 32 + hashLen = 32 + extraLen = 32 + versionLen = 16 + ) + var keyBuf [privKeyLen + hashLen + extraLen + versionLen]byte + + // Truncate rightmost bytes of private key and hash if they are too long and + // leave left padding of zeros when they're too short. + if len(privKey) > privKeyLen { + privKey = privKey[:privKeyLen] + } + if len(hash) > hashLen { + hash = hash[:hashLen] + } + offset := privKeyLen - len(privKey) // Zero left padding if needed. + offset += copy(keyBuf[offset:], privKey) + offset += hashLen - len(hash) // Zero left padding if needed. + offset += copy(keyBuf[offset:], hash) + if len(extra) == extraLen { + offset += copy(keyBuf[offset:], extra) + if len(version) == versionLen { + offset += copy(keyBuf[offset:], version) + } + } else if len(version) == versionLen { + // When the version was specified, but not the extra data, leave the + // extra data portion all zero. + offset += privKeyLen + offset += copy(keyBuf[offset:], version) + } + key := keyBuf[:offset] + + // Step B. + // + // V = 0x01 0x01 0x01 ... 0x01 such that the length of V, in bits, is + // equal to 8*ceil(hashLen/8). + // + // Note that since the hash length is a multiple of 8 for the chosen hash + // function in this optimized implementation, the result is just the hash + // length, so avoid the extra calculations. Also, since it isn't modified, + // start with a global value. + v := oneInitializer + + // Step C (Go zeroes all allocated memory). + // + // K = 0x00 0x00 0x00 ... 0x00 such that the length of K, in bits, is + // equal to 8*ceil(hashLen/8). + // + // As above, since the hash length is a multiple of 8 for the chosen hash + // function in this optimized implementation, the result is just the hash + // length, so avoid the extra calculations. + k := zeroInitializer[:hashLen] + + // Step D. + // + // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1)) + // + // Note that key is the "int2octets(x) || bits2octets(h1)" portion along + // with potential additional data as described by section 3.6 of the RFC. + hasher := newHMACSHA256(k) + hasher.Write(oneInitializer) + hasher.Write(singleZero[:]) + hasher.Write(key) + k = hasher.Sum() + + // Step E. + // + // V = HMAC_K(V) + hasher.ResetKey(k) + hasher.Write(v) + v = hasher.Sum() + + // Step F. + // + // K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1)) + // + // Note that key is the "int2octets(x) || bits2octets(h1)" portion along + // with potential additional data as described by section 3.6 of the RFC. + hasher.Reset() + hasher.Write(v) + hasher.Write(singleOne[:]) + hasher.Write(key[:]) + k = hasher.Sum() + + // Step G. + // + // V = HMAC_K(V) + hasher.ResetKey(k) + hasher.Write(v) + v = hasher.Sum() + + // Step H. + // + // Repeat until the value is nonzero and less than the curve order. + var generated uint32 + for { + // Step H1 and H2. + // + // Set T to the empty sequence. The length of T (in bits) is denoted + // tlen; thus, at that point, tlen = 0. + // + // While tlen < qlen, do the following: + // V = HMAC_K(V) + // T = T || V + // + // Note that because the hash function output is the same length as the + // private key in this optimized implementation, there is no need to + // loop or create an intermediate T. + hasher.Reset() + hasher.Write(v) + v = hasher.Sum() + + // Step H3. + // + // k = bits2int(T) + // If k is within the range [1,q-1], return it. + // + // Otherwise, compute: + // K = HMAC_K(V || 0x00) + // V = HMAC_K(V) + var secret ModNScalar + overflow := secret.SetByteSlice(v) + if !overflow && !secret.IsZero() { + generated++ + if generated > extraIterations { + return &secret + } + } + + // K = HMAC_K(V || 0x00) + hasher.Reset() + hasher.Write(v) + hasher.Write(singleZero[:]) + k = hasher.Sum() + + // V = HMAC_K(V) + hasher.ResetKey(k) + hasher.Write(v) + v = hasher.Sum() + } +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go new file mode 100644 index 000000000..ca3e8da28 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go @@ -0,0 +1,111 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2023 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + cryptorand "crypto/rand" + "io" +) + +// PrivateKey provides facilities for working with secp256k1 private keys within +// this package and includes functionality such as serializing and parsing them +// as well as computing their associated public key. +type PrivateKey struct { + Key ModNScalar +} + +// NewPrivateKey instantiates a new private key from a scalar encoded as a +// big integer. +func NewPrivateKey(key *ModNScalar) *PrivateKey { + return &PrivateKey{Key: *key} +} + +// PrivKeyFromBytes returns a private based on the provided byte slice which is +// interpreted as an unsigned 256-bit big-endian integer in the range [0, N-1], +// where N is the order of the curve. +// +// WARNING: This means passing a slice with more than 32 bytes is truncated and +// that truncated value is reduced modulo N. Further, 0 is not a valid private +// key. It is up to the caller to provide a value in the appropriate range of +// [1, N-1]. Failure to do so will either result in an invalid private key or +// potentially weak private keys that have bias that could be exploited. +// +// This function primarily exists to provide a mechanism for converting +// serialized private keys that are already known to be good. +// +// Typically callers should make use of GeneratePrivateKey or +// GeneratePrivateKeyFromRand when creating private keys since they properly +// handle generation of appropriate values. +func PrivKeyFromBytes(privKeyBytes []byte) *PrivateKey { + var privKey PrivateKey + privKey.Key.SetByteSlice(privKeyBytes) + return &privKey +} + +// generatePrivateKey generates and returns a new private key that is suitable +// for use with secp256k1 using the provided reader as a source of entropy. The +// provided reader must be a source of cryptographically secure randomness to +// avoid weak private keys. +func generatePrivateKey(rand io.Reader) (*PrivateKey, error) { + // The group order is close enough to 2^256 that there is only roughly a 1 + // in 2^128 chance of generating an invalid private key, so this loop will + // virtually never run more than a single iteration in practice. + var key PrivateKey + var b32 [32]byte + for valid := false; !valid; { + if _, err := io.ReadFull(rand, b32[:]); err != nil { + return nil, err + } + + // The private key is only valid when it is in the range [1, N-1], where + // N is the order of the curve. + overflow := key.Key.SetBytes(&b32) + valid = (key.Key.IsZeroBit() | overflow) == 0 + } + zeroArray32(&b32) + + return &key, nil +} + +// GeneratePrivateKey generates and returns a new cryptographically secure +// private key that is suitable for use with secp256k1. +func GeneratePrivateKey() (*PrivateKey, error) { + return generatePrivateKey(cryptorand.Reader) +} + +// GeneratePrivateKeyFromRand generates a private key that is suitable for use +// with secp256k1 using the provided reader as a source of entropy. The +// provided reader must be a source of cryptographically secure randomness, such +// as [crypto/rand.Reader], to avoid weak private keys. +func GeneratePrivateKeyFromRand(rand io.Reader) (*PrivateKey, error) { + return generatePrivateKey(rand) +} + +// PubKey computes and returns the public key corresponding to this private key. +func (p *PrivateKey) PubKey() *PublicKey { + var result JacobianPoint + ScalarBaseMultNonConst(&p.Key, &result) + result.ToAffine() + return NewPublicKey(&result.X, &result.Y) +} + +// Zero manually clears the memory associated with the private key. This can be +// used to explicitly clear key material from memory for enhanced security +// against memory scraping. +func (p *PrivateKey) Zero() { + p.Key.Zero() +} + +// PrivKeyBytesLen defines the length in bytes of a serialized private key. +const PrivKeyBytesLen = 32 + +// Serialize returns the private key as a 256-bit big-endian binary-encoded +// number, padded to a length of 32 bytes. +func (p PrivateKey) Serialize() []byte { + var privKeyBytes [PrivKeyBytesLen]byte + p.Key.PutBytes(&privKeyBytes) + return privKeyBytes[:] +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go new file mode 100644 index 000000000..54c54be5f --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go @@ -0,0 +1,237 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2022 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// References: +// [SEC1] Elliptic Curve Cryptography +// https://www.secg.org/sec1-v2.pdf +// +// [SEC2] Recommended Elliptic Curve Domain Parameters +// https://www.secg.org/sec2-v2.pdf +// +// [ANSI X9.62-1998] Public Key Cryptography For The Financial Services +// Industry: The Elliptic Curve Digital Signature Algorithm (ECDSA) + +import ( + "fmt" +) + +const ( + // PubKeyBytesLenCompressed is the number of bytes of a serialized + // compressed public key. + PubKeyBytesLenCompressed = 33 + + // PubKeyBytesLenUncompressed is the number of bytes of a serialized + // uncompressed public key. + PubKeyBytesLenUncompressed = 65 + + // PubKeyFormatCompressedEven is the identifier prefix byte for a public key + // whose Y coordinate is even when serialized in the compressed format per + // section 2.3.4 of [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.4). + PubKeyFormatCompressedEven byte = 0x02 + + // PubKeyFormatCompressedOdd is the identifier prefix byte for a public key + // whose Y coordinate is odd when serialized in the compressed format per + // section 2.3.4 of [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.4). + PubKeyFormatCompressedOdd byte = 0x03 + + // PubKeyFormatUncompressed is the identifier prefix byte for a public key + // when serialized according in the uncompressed format per section 2.3.3 of + // [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.3). + PubKeyFormatUncompressed byte = 0x04 + + // PubKeyFormatHybridEven is the identifier prefix byte for a public key + // whose Y coordinate is even when serialized according to the hybrid format + // per section 4.3.6 of [ANSI X9.62-1998]. + // + // NOTE: This format makes little sense in practice an therefore this + // package will not produce public keys serialized in this format. However, + // it will parse them since they exist in the wild. + PubKeyFormatHybridEven byte = 0x06 + + // PubKeyFormatHybridOdd is the identifier prefix byte for a public key + // whose Y coordingate is odd when serialized according to the hybrid format + // per section 4.3.6 of [ANSI X9.62-1998]. + // + // NOTE: This format makes little sense in practice an therefore this + // package will not produce public keys serialized in this format. However, + // it will parse them since they exist in the wild. + PubKeyFormatHybridOdd byte = 0x07 +) + +// PublicKey provides facilities for efficiently working with secp256k1 public +// keys within this package and includes functions to serialize in both +// uncompressed and compressed SEC (Standards for Efficient Cryptography) +// formats. +type PublicKey struct { + x FieldVal + y FieldVal +} + +// NewPublicKey instantiates a new public key with the given x and y +// coordinates. +// +// It should be noted that, unlike ParsePubKey, since this accepts arbitrary x +// and y coordinates, it allows creation of public keys that are not valid +// points on the secp256k1 curve. The IsOnCurve method of the returned instance +// can be used to determine validity. +func NewPublicKey(x, y *FieldVal) *PublicKey { + var pubKey PublicKey + pubKey.x.Set(x) + pubKey.y.Set(y) + return &pubKey +} + +// ParsePubKey parses a secp256k1 public key encoded according to the format +// specified by ANSI X9.62-1998, which means it is also compatible with the +// SEC (Standards for Efficient Cryptography) specification which is a subset of +// the former. In other words, it supports the uncompressed, compressed, and +// hybrid formats as follows: +// +// Compressed: +// +// <32-byte X coordinate> +// +// Uncompressed: +// +// <32-byte X coordinate><32-byte Y coordinate> +// +// Hybrid: +// +// <32-byte X coordinate><32-byte Y coordinate> +// +// NOTE: The hybrid format makes little sense in practice an therefore this +// package will not produce public keys serialized in this format. However, +// this function will properly parse them since they exist in the wild. +func ParsePubKey(serialized []byte) (key *PublicKey, err error) { + var x, y FieldVal + switch len(serialized) { + case PubKeyBytesLenUncompressed: + // Reject unsupported public key formats for the given length. + format := serialized[0] + switch format { + case PubKeyFormatUncompressed: + case PubKeyFormatHybridEven, PubKeyFormatHybridOdd: + default: + str := fmt.Sprintf("invalid public key: unsupported format: %x", + format) + return nil, makeError(ErrPubKeyInvalidFormat, str) + } + + // Parse the x and y coordinates while ensuring that they are in the + // allowed range. + if overflow := x.SetByteSlice(serialized[1:33]); overflow { + str := "invalid public key: x >= field prime" + return nil, makeError(ErrPubKeyXTooBig, str) + } + if overflow := y.SetByteSlice(serialized[33:]); overflow { + str := "invalid public key: y >= field prime" + return nil, makeError(ErrPubKeyYTooBig, str) + } + + // Ensure the oddness of the y coordinate matches the specified format + // for hybrid public keys. + if format == PubKeyFormatHybridEven || format == PubKeyFormatHybridOdd { + wantOddY := format == PubKeyFormatHybridOdd + if y.IsOdd() != wantOddY { + str := fmt.Sprintf("invalid public key: y oddness does not "+ + "match specified value of %v", wantOddY) + return nil, makeError(ErrPubKeyMismatchedOddness, str) + } + } + + // Reject public keys that are not on the secp256k1 curve. + if !isOnCurve(&x, &y) { + str := fmt.Sprintf("invalid public key: [%v,%v] not on secp256k1 "+ + "curve", x, y) + return nil, makeError(ErrPubKeyNotOnCurve, str) + } + + case PubKeyBytesLenCompressed: + // Reject unsupported public key formats for the given length. + format := serialized[0] + switch format { + case PubKeyFormatCompressedEven, PubKeyFormatCompressedOdd: + default: + str := fmt.Sprintf("invalid public key: unsupported format: %x", + format) + return nil, makeError(ErrPubKeyInvalidFormat, str) + } + + // Parse the x coordinate while ensuring that it is in the allowed + // range. + if overflow := x.SetByteSlice(serialized[1:33]); overflow { + str := "invalid public key: x >= field prime" + return nil, makeError(ErrPubKeyXTooBig, str) + } + + // Attempt to calculate the y coordinate for the given x coordinate such + // that the result pair is a point on the secp256k1 curve and the + // solution with desired oddness is chosen. + wantOddY := format == PubKeyFormatCompressedOdd + if !DecompressY(&x, wantOddY, &y) { + str := fmt.Sprintf("invalid public key: x coordinate %v is not on "+ + "the secp256k1 curve", x) + return nil, makeError(ErrPubKeyNotOnCurve, str) + } + y.Normalize() + + default: + str := fmt.Sprintf("malformed public key: invalid length: %d", + len(serialized)) + return nil, makeError(ErrPubKeyInvalidLen, str) + } + + return NewPublicKey(&x, &y), nil +} + +// SerializeUncompressed serializes a public key in the 65-byte uncompressed +// format. +func (p PublicKey) SerializeUncompressed() []byte { + // 0x04 || 32-byte x coordinate || 32-byte y coordinate + var b [PubKeyBytesLenUncompressed]byte + b[0] = PubKeyFormatUncompressed + p.x.PutBytesUnchecked(b[1:33]) + p.y.PutBytesUnchecked(b[33:65]) + return b[:] +} + +// SerializeCompressed serializes a public key in the 33-byte compressed format. +func (p PublicKey) SerializeCompressed() []byte { + // Choose the format byte depending on the oddness of the Y coordinate. + format := PubKeyFormatCompressedEven + if p.y.IsOdd() { + format = PubKeyFormatCompressedOdd + } + + // 0x02 or 0x03 || 32-byte x coordinate + var b [PubKeyBytesLenCompressed]byte + b[0] = format + p.x.PutBytesUnchecked(b[1:33]) + return b[:] +} + +// IsEqual compares this public key instance to the one passed, returning true +// if both public keys are equivalent. A public key is equivalent to another, +// if they both have the same X and Y coordinates. +func (p *PublicKey) IsEqual(otherPubKey *PublicKey) bool { + return p.x.Equals(&otherPubKey.x) && p.y.Equals(&otherPubKey.y) +} + +// AsJacobian converts the public key into a Jacobian point with Z=1 and stores +// the result in the provided result param. This allows the public key to be +// treated a Jacobian point in the secp256k1 group in calculations. +func (p *PublicKey) AsJacobian(result *JacobianPoint) { + result.X.Set(&p.x) + result.Y.Set(&p.y) + result.Z.SetInt(1) +} + +// IsOnCurve returns whether or not the public key represents a point on the +// secp256k1 curve. +func (p *PublicKey) IsOnCurve() bool { + return isOnCurve(&p.x, &p.y) +} diff --git a/vendor/github.com/digitorus/pkcs7/Makefile b/vendor/github.com/digitorus/pkcs7/Makefile index 47c73b868..07c78e14c 100644 --- a/vendor/github.com/digitorus/pkcs7/Makefile +++ b/vendor/github.com/digitorus/pkcs7/Makefile @@ -1,7 +1,7 @@ all: vet staticcheck test test: - go test -covermode=count -coverprofile=coverage.out . + GODEBUG=x509sha1=1 go test -covermode=count -coverprofile=coverage.out . showcoverage: test go tool cover -html=coverage.out diff --git a/vendor/github.com/digitorus/pkcs7/ber.go b/vendor/github.com/digitorus/pkcs7/ber.go index 73da024a0..31963b119 100644 --- a/vendor/github.com/digitorus/pkcs7/ber.go +++ b/vendor/github.com/digitorus/pkcs7/ber.go @@ -5,8 +5,6 @@ import ( "errors" ) -var encodeIndent = 0 - type asn1Object interface { EncodeTo(writer *bytes.Buffer) error } @@ -18,7 +16,6 @@ type asn1Structured struct { func (s asn1Structured) EncodeTo(out *bytes.Buffer) error { //fmt.Printf("%s--> tag: % X\n", strings.Repeat("| ", encodeIndent), s.tagBytes) - encodeIndent++ inner := new(bytes.Buffer) for _, obj := range s.content { err := obj.EncodeTo(inner) @@ -26,7 +23,6 @@ func (s asn1Structured) EncodeTo(out *bytes.Buffer) error { return err } } - encodeIndent-- out.Write(s.tagBytes) encodeLength(out, inner.Len()) out.Write(inner.Bytes()) @@ -67,10 +63,6 @@ func ber2der(ber []byte) ([]byte, error) { } obj.EncodeTo(out) - // if offset < len(ber) { - // return nil, fmt.Errorf("ber2der: Content longer than expected. Got %d, expected %d", offset, len(ber)) - //} - return out.Bytes(), nil } @@ -149,14 +141,14 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) { for ber[offset] >= 0x80 { tag = tag*128 + ber[offset] - 0x80 offset++ - if offset > berLen { + if offset >= berLen { return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached") } } // jvehent 20170227: this doesn't appear to be used anywhere... //tag = tag*128 + ber[offset] - 0x80 offset++ - if offset > berLen { + if offset >= berLen { return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached") } } @@ -172,7 +164,10 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) { var length int l := ber[offset] offset++ - if offset > berLen { + if l >= 0x80 && offset >= berLen { + // if indefinite or multibyte length, we need to verify there is at least one more byte available + // otherwise we need to be flexible here for length == 0 conditions + // validation that the length is available is done after the length is correctly parsed return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached") } indefinite := false @@ -184,17 +179,20 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) { if numberOfBytes == 4 && (int)(ber[offset]) > 0x7F { return nil, 0, errors.New("ber2der: BER tag length is negative") } - if (int)(ber[offset]) == 0x0 { + if offset + numberOfBytes > berLen { + // == condition is not checked here, this allows for a more descreptive error when the parsed length is + // compared with the remaining available bytes (`contentEnd > berLen`) + return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached") + } + if (int)(ber[offset]) == 0x0 && (numberOfBytes == 1 || ber[offset+1] <= 0x7F) { + // `numberOfBytes == 1` is an important conditional to avoid a potential out of bounds panic with `ber[offset+1]` return nil, 0, errors.New("ber2der: BER tag length has leading zero") } debugprint("--> (compute length) indicator byte: %x\n", l) - debugprint("--> (compute length) length bytes: % X\n", ber[offset:offset+numberOfBytes]) + //debugprint("--> (compute length) length bytes: %x\n", ber[offset:offset+numberOfBytes]) for i := 0; i < numberOfBytes; i++ { length = length*256 + (int)(ber[offset]) offset++ - if offset > berLen { - return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached") - } } } else if l == 0x80 { indefinite = true @@ -206,12 +204,12 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) { } //fmt.Printf("--> length : %d\n", length) contentEnd := offset + length - if contentEnd > len(ber) { + if contentEnd > berLen { return nil, 0, errors.New("ber2der: BER tag length is more than available data") } debugprint("--> content start : %d\n", offset) debugprint("--> content end : %d\n", contentEnd) - debugprint("--> content : % X\n", ber[offset:contentEnd]) + //debugprint("--> content : %x\n", ber[offset:contentEnd]) var obj asn1Object if indefinite && kind == 0 { return nil, 0, errors.New("ber2der: Indefinite form tag must have constructed encoding") diff --git a/vendor/github.com/digitorus/pkcs7/pkcs7.go b/vendor/github.com/digitorus/pkcs7/pkcs7.go index 0b74dff9b..aca3c53f4 100644 --- a/vendor/github.com/digitorus/pkcs7/pkcs7.go +++ b/vendor/github.com/digitorus/pkcs7/pkcs7.go @@ -101,9 +101,9 @@ func getHashForOID(oid asn1.ObjectIdentifier) (crypto.Hash, error) { return crypto.Hash(0), ErrUnsupportedAlgorithm } -// getDigestOIDForSignatureAlgorithm takes an x509.SignatureAlgorithm +// GetDigestOIDForSignatureAlgorithm takes an x509.SignatureAlgorithm // and returns the corresponding OID digest algorithm -func getDigestOIDForSignatureAlgorithm(digestAlg x509.SignatureAlgorithm) (asn1.ObjectIdentifier, error) { +func GetDigestOIDForSignatureAlgorithm(digestAlg x509.SignatureAlgorithm) (asn1.ObjectIdentifier, error) { switch digestAlg { case x509.SHA1WithRSA, x509.ECDSAWithSHA1: return OIDDigestAlgorithmSHA1, nil diff --git a/vendor/github.com/digitorus/timestamp/rfc3161_struct.go b/vendor/github.com/digitorus/timestamp/rfc3161_struct.go index 04060dd02..c5692253c 100644 --- a/vendor/github.com/digitorus/timestamp/rfc3161_struct.go +++ b/vendor/github.com/digitorus/timestamp/rfc3161_struct.go @@ -45,7 +45,7 @@ func (s pkiStatusInfo) FailureInfo() FailureInfo { } } - return UnkownFailureInfo + return UnknownFailureInfo } // eContent within SignedData is TSTInfo diff --git a/vendor/github.com/digitorus/timestamp/timestamp.go b/vendor/github.com/digitorus/timestamp/timestamp.go index 8069cad8f..9e6da2d92 100644 --- a/vendor/github.com/digitorus/timestamp/timestamp.go +++ b/vendor/github.com/digitorus/timestamp/timestamp.go @@ -23,8 +23,8 @@ import ( type FailureInfo int const ( - // UnkownFailureInfo mean that no known failure info was provided - UnkownFailureInfo FailureInfo = -1 + // UnknownFailureInfo mean that no known failure info was provided + UnknownFailureInfo FailureInfo = -1 // BadAlgorithm defines an unrecognized or unsupported Algorithm Identifier BadAlgorithm FailureInfo = 0 // BadRequest indicates that the transaction not permitted or supported @@ -268,7 +268,7 @@ func ParseResponse(bytes []byte) (*Timestamp, error) { if resp.Status.Status > 0 { var fis string fi := resp.Status.FailureInfo() - if fi != UnkownFailureInfo { + if fi != UnknownFailureInfo { fis = fi.String() } return nil, fmt.Errorf("%s: %s (%v)", @@ -405,12 +405,12 @@ func CreateRequest(r io.Reader, opts *RequestOptions) ([]byte, error) { return req.Marshal() } -// CreateResponse returns a DER-encoded timestamp response with the specified contents. +// CreateResponseWithOpts returns a DER-encoded timestamp response with the specified contents. // The fields in the response are populated as follows: // // The responder cert is used to populate the responder's name field, and the // certificate itself is provided alongside the timestamp response signature. -func (t *Timestamp) CreateResponse(signingCert *x509.Certificate, priv crypto.Signer) ([]byte, error) { +func (t *Timestamp) CreateResponseWithOpts(signingCert *x509.Certificate, priv crypto.Signer, opts crypto.SignerOpts) ([]byte, error) { messageImprint := getMessageImprint(t.HashAlgorithm, t.HashedMessage) tsaSerialNumber, err := generateTSASerialNumber() @@ -421,7 +421,7 @@ func (t *Timestamp) CreateResponse(signingCert *x509.Certificate, priv crypto.Si if err != nil { return nil, err } - signature, err := t.generateSignedData(tstInfo, priv, signingCert) + signature, err := t.generateSignedData(tstInfo, priv, signingCert, opts) if err != nil { return nil, err } @@ -438,6 +438,19 @@ func (t *Timestamp) CreateResponse(signingCert *x509.Certificate, priv crypto.Si return tspResponseBytes, nil } +// CreateResponse returns a DER-encoded timestamp response with the specified contents. +// The fields in the response are populated as follows: +// +// The responder cert is used to populate the responder's name field, and the +// certificate itself is provided alongside the timestamp response signature. +// +// This function is equivalent to CreateResponseWithOpts, using a SHA256 hash. +// +// Deprecated: Use CreateResponseWithOpts instead. +func (t *Timestamp) CreateResponse(signingCert *x509.Certificate, priv crypto.Signer) ([]byte, error) { + return t.CreateResponseWithOpts(signingCert, priv, crypto.SHA256) +} + // CreateErrorResponse is used to create response other than granted and granted with mod status func CreateErrorResponse(pkiStatus Status, pkiFailureInfo FailureInfo) ([]byte, error) { var bs asn1.BitString @@ -553,7 +566,7 @@ func (t *Timestamp) populateSigningCertificateV2Ext(certificate *x509.Certificat return nil, x509.ErrUnsupportedAlgorithm } if t.HashAlgorithm.HashFunc() == crypto.SHA1 { - return nil, fmt.Errorf("for SHA1 usae ESSCertID instead of ESSCertIDv2") + return nil, fmt.Errorf("for SHA1 use ESSCertID instead of ESSCertIDv2") } h := t.HashAlgorithm.HashFunc().New() @@ -591,12 +604,33 @@ func (t *Timestamp) populateSigningCertificateV2Ext(certificate *x509.Certificat return signingCertV2Bytes, nil } -func (t *Timestamp) generateSignedData(tstInfo []byte, signer crypto.Signer, certificate *x509.Certificate) ([]byte, error) { +// digestAlgorithmToOID converts the hash func to the corresponding OID. +// This should have parity with [pkcs7.getHashForOID]. +func digestAlgorithmToOID(hash crypto.Hash) (asn1.ObjectIdentifier, error) { + switch hash { + case crypto.SHA1: + return pkcs7.OIDDigestAlgorithmSHA1, nil + case crypto.SHA256: + return pkcs7.OIDDigestAlgorithmSHA256, nil + case crypto.SHA384: + return pkcs7.OIDDigestAlgorithmSHA384, nil + case crypto.SHA512: + return pkcs7.OIDDigestAlgorithmSHA512, nil + } + return nil, pkcs7.ErrUnsupportedAlgorithm +} + +func (t *Timestamp) generateSignedData(tstInfo []byte, signer crypto.Signer, certificate *x509.Certificate, opts crypto.SignerOpts) ([]byte, error) { signedData, err := pkcs7.NewSignedData(tstInfo) if err != nil { return nil, err } - signedData.SetDigestAlgorithm(pkcs7.OIDDigestAlgorithmSHA256) + + alg, err := digestAlgorithmToOID(opts.HashFunc()) + if err != nil { + return nil, err + } + signedData.SetDigestAlgorithm(alg) signedData.SetContentType(asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 1, 4}) signingCertV2Bytes, err := t.populateSigningCertificateV2Ext(certificate) @@ -616,7 +650,11 @@ func (t *Timestamp) generateSignedData(tstInfo []byte, signer crypto.Signer, cer signerInfoConfig.SkipCertificates = true } - err = signedData.AddSigner(certificate, signer, signerInfoConfig) + if len(t.Certificates) > 0 { + err = signedData.AddSignerChain(certificate, signer, t.Certificates, signerInfoConfig) + } else { + err = signedData.AddSigner(certificate, signer, signerInfoConfig) + } if err != nil { return nil, err } @@ -628,7 +666,7 @@ func (t *Timestamp) generateSignedData(tstInfo []byte, signer crypto.Signer, cer return signature, nil } -// copied from cryto/x509 package +// copied from crypto/x509 package // oidNotInExtensions reports whether an extension with the given oid exists in // extensions. func oidInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extension) bool { diff --git a/vendor/github.com/distribution/reference/.gitattributes b/vendor/github.com/distribution/reference/.gitattributes new file mode 100644 index 000000000..d207b1802 --- /dev/null +++ b/vendor/github.com/distribution/reference/.gitattributes @@ -0,0 +1 @@ +*.go text eol=lf diff --git a/vendor/github.com/distribution/reference/.gitignore b/vendor/github.com/distribution/reference/.gitignore new file mode 100644 index 000000000..dc07e6b04 --- /dev/null +++ b/vendor/github.com/distribution/reference/.gitignore @@ -0,0 +1,2 @@ +# Cover profiles +*.out diff --git a/vendor/github.com/distribution/reference/.golangci.yml b/vendor/github.com/distribution/reference/.golangci.yml new file mode 100644 index 000000000..793f0bb7e --- /dev/null +++ b/vendor/github.com/distribution/reference/.golangci.yml @@ -0,0 +1,18 @@ +linters: + enable: + - bodyclose + - dupword # Checks for duplicate words in the source code + - gofmt + - goimports + - ineffassign + - misspell + - revive + - staticcheck + - unconvert + - unused + - vet + disable: + - errcheck + +run: + deadline: 2m diff --git a/vendor/github.com/distribution/reference/CODE-OF-CONDUCT.md b/vendor/github.com/distribution/reference/CODE-OF-CONDUCT.md new file mode 100644 index 000000000..48f6704c6 --- /dev/null +++ b/vendor/github.com/distribution/reference/CODE-OF-CONDUCT.md @@ -0,0 +1,5 @@ +# Code of Conduct + +We follow the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). + +Please contact the [CNCF Code of Conduct Committee](mailto:conduct@cncf.io) in order to report violations of the Code of Conduct. diff --git a/vendor/github.com/distribution/reference/CONTRIBUTING.md b/vendor/github.com/distribution/reference/CONTRIBUTING.md new file mode 100644 index 000000000..ab2194665 --- /dev/null +++ b/vendor/github.com/distribution/reference/CONTRIBUTING.md @@ -0,0 +1,114 @@ +# Contributing to the reference library + +## Community help + +If you need help, please ask in the [#distribution](https://cloud-native.slack.com/archives/C01GVR8SY4R) channel on CNCF community slack. +[Click here for an invite to the CNCF community slack](https://slack.cncf.io/) + +## Reporting security issues + +The maintainers take security seriously. If you discover a security +issue, please bring it to their attention right away! + +Please **DO NOT** file a public issue, instead send your report privately to +[cncf-distribution-security@lists.cncf.io](mailto:cncf-distribution-security@lists.cncf.io). + +## Reporting an issue properly + +By following these simple rules you will get better and faster feedback on your issue. + + - search the bugtracker for an already reported issue + +### If you found an issue that describes your problem: + + - please read other user comments first, and confirm this is the same issue: a given error condition might be indicative of different problems - you may also find a workaround in the comments + - please refrain from adding "same thing here" or "+1" comments + - you don't need to comment on an issue to get notified of updates: just hit the "subscribe" button + - comment if you have some new, technical and relevant information to add to the case + - __DO NOT__ comment on closed issues or merged PRs. If you think you have a related problem, open up a new issue and reference the PR or issue. + +### If you have not found an existing issue that describes your problem: + + 1. create a new issue, with a succinct title that describes your issue: + - bad title: "It doesn't work with my docker" + - good title: "Private registry push fail: 400 error with E_INVALID_DIGEST" + 2. copy the output of (or similar for other container tools): + - `docker version` + - `docker info` + - `docker exec registry --version` + 3. copy the command line you used to launch your Registry + 4. restart your docker daemon in debug mode (add `-D` to the daemon launch arguments) + 5. reproduce your problem and get your docker daemon logs showing the error + 6. if relevant, copy your registry logs that show the error + 7. provide any relevant detail about your specific Registry configuration (e.g., storage backend used) + 8. indicate if you are using an enterprise proxy, Nginx, or anything else between you and your Registry + +## Contributing Code + +Contributions should be made via pull requests. Pull requests will be reviewed +by one or more maintainers or reviewers and merged when acceptable. + +You should follow the basic GitHub workflow: + + 1. Use your own [fork](https://help.github.com/en/articles/about-forks) + 2. Create your [change](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#successful-changes) + 3. Test your code + 4. [Commit](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#commit-messages) your work, always [sign your commits](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#commit-messages) + 5. Push your change to your fork and create a [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) + +Refer to [containerd's contribution guide](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#successful-changes) +for tips on creating a successful contribution. + +## Sign your work + +The sign-off is a simple line at the end of the explanation for the patch. Your +signature certifies that you wrote the patch or otherwise have the right to pass +it on as an open-source patch. The rules are pretty simple: if you can certify +the below (from [developercertificate.org](http://developercertificate.org/)): + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +660 York Street, Suite 102, +San Francisco, CA 94110 USA + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +Then you just add a line to every git commit message: + + Signed-off-by: Joe Smith + +Use your real name (sorry, no pseudonyms or anonymous contributions.) + +If you set your `user.name` and `user.email` git configs, you can sign your +commit automatically with `git commit -s`. diff --git a/vendor/github.com/distribution/reference/GOVERNANCE.md b/vendor/github.com/distribution/reference/GOVERNANCE.md new file mode 100644 index 000000000..200045b05 --- /dev/null +++ b/vendor/github.com/distribution/reference/GOVERNANCE.md @@ -0,0 +1,144 @@ +# distribution/reference Project Governance + +Distribution [Code of Conduct](./CODE-OF-CONDUCT.md) can be found here. + +For specific guidance on practical contribution steps please +see our [CONTRIBUTING.md](./CONTRIBUTING.md) guide. + +## Maintainership + +There are different types of maintainers, with different responsibilities, but +all maintainers have 3 things in common: + +1) They share responsibility in the project's success. +2) They have made a long-term, recurring time investment to improve the project. +3) They spend that time doing whatever needs to be done, not necessarily what +is the most interesting or fun. + +Maintainers are often under-appreciated, because their work is harder to appreciate. +It's easy to appreciate a really cool and technically advanced feature. It's harder +to appreciate the absence of bugs, the slow but steady improvement in stability, +or the reliability of a release process. But those things distinguish a good +project from a great one. + +## Reviewers + +A reviewer is a core role within the project. +They share in reviewing issues and pull requests and their LGTM counts towards the +required LGTM count to merge a code change into the project. + +Reviewers are part of the organization but do not have write access. +Becoming a reviewer is a core aspect in the journey to becoming a maintainer. + +## Adding maintainers + +Maintainers are first and foremost contributors that have shown they are +committed to the long term success of a project. Contributors wanting to become +maintainers are expected to be deeply involved in contributing code, pull +request review, and triage of issues in the project for more than three months. + +Just contributing does not make you a maintainer, it is about building trust +with the current maintainers of the project and being a person that they can +depend on and trust to make decisions in the best interest of the project. + +Periodically, the existing maintainers curate a list of contributors that have +shown regular activity on the project over the prior months. From this list, +maintainer candidates are selected and proposed in a pull request or a +maintainers communication channel. + +After a candidate has been announced to the maintainers, the existing +maintainers are given five business days to discuss the candidate, raise +objections and cast their vote. Votes may take place on the communication +channel or via pull request comment. Candidates must be approved by at least 66% +of the current maintainers by adding their vote on the mailing list. The +reviewer role has the same process but only requires 33% of current maintainers. +Only maintainers of the repository that the candidate is proposed for are +allowed to vote. + +If a candidate is approved, a maintainer will contact the candidate to invite +the candidate to open a pull request that adds the contributor to the +MAINTAINERS file. The voting process may take place inside a pull request if a +maintainer has already discussed the candidacy with the candidate and a +maintainer is willing to be a sponsor by opening the pull request. The candidate +becomes a maintainer once the pull request is merged. + +## Stepping down policy + +Life priorities, interests, and passions can change. If you're a maintainer but +feel you must remove yourself from the list, inform other maintainers that you +intend to step down, and if possible, help find someone to pick up your work. +At the very least, ensure your work can be continued where you left off. + +After you've informed other maintainers, create a pull request to remove +yourself from the MAINTAINERS file. + +## Removal of inactive maintainers + +Similar to the procedure for adding new maintainers, existing maintainers can +be removed from the list if they do not show significant activity on the +project. Periodically, the maintainers review the list of maintainers and their +activity over the last three months. + +If a maintainer has shown insufficient activity over this period, a neutral +person will contact the maintainer to ask if they want to continue being +a maintainer. If the maintainer decides to step down as a maintainer, they +open a pull request to be removed from the MAINTAINERS file. + +If the maintainer wants to remain a maintainer, but is unable to perform the +required duties they can be removed with a vote of at least 66% of the current +maintainers. In this case, maintainers should first propose the change to +maintainers via the maintainers communication channel, then open a pull request +for voting. The voting period is five business days. The voting pull request +should not come as a surpise to any maintainer and any discussion related to +performance must not be discussed on the pull request. + +## How are decisions made? + +Docker distribution is an open-source project with an open design philosophy. +This means that the repository is the source of truth for EVERY aspect of the +project, including its philosophy, design, road map, and APIs. *If it's part of +the project, it's in the repo. If it's in the repo, it's part of the project.* + +As a result, all decisions can be expressed as changes to the repository. An +implementation change is a change to the source code. An API change is a change +to the API specification. A philosophy change is a change to the philosophy +manifesto, and so on. + +All decisions affecting distribution, big and small, follow the same 3 steps: + +* Step 1: Open a pull request. Anyone can do this. + +* Step 2: Discuss the pull request. Anyone can do this. + +* Step 3: Merge or refuse the pull request. Who does this depends on the nature +of the pull request and which areas of the project it affects. + +## Helping contributors with the DCO + +The [DCO or `Sign your work`](./CONTRIBUTING.md#sign-your-work) +requirement is not intended as a roadblock or speed bump. + +Some contributors are not as familiar with `git`, or have used a web +based editor, and thus asking them to `git commit --amend -s` is not the best +way forward. + +In this case, maintainers can update the commits based on clause (c) of the DCO. +The most trivial way for a contributor to allow the maintainer to do this, is to +add a DCO signature in a pull requests's comment, or a maintainer can simply +note that the change is sufficiently trivial that it does not substantially +change the existing contribution - i.e., a spelling change. + +When you add someone's DCO, please also add your own to keep a log. + +## I'm a maintainer. Should I make pull requests too? + +Yes. Nobody should ever push to master directly. All changes should be +made through a pull request. + +## Conflict Resolution + +If you have a technical dispute that you feel has reached an impasse with a +subset of the community, any contributor may open an issue, specifically +calling for a resolution vote of the current core maintainers to resolve the +dispute. The same voting quorums required (2/3) for adding and removing +maintainers will apply to conflict resolution. diff --git a/vendor/github.com/distribution/reference/LICENSE b/vendor/github.com/distribution/reference/LICENSE new file mode 100644 index 000000000..e06d20818 --- /dev/null +++ b/vendor/github.com/distribution/reference/LICENSE @@ -0,0 +1,202 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/vendor/github.com/distribution/reference/MAINTAINERS b/vendor/github.com/distribution/reference/MAINTAINERS new file mode 100644 index 000000000..9e0a60c8b --- /dev/null +++ b/vendor/github.com/distribution/reference/MAINTAINERS @@ -0,0 +1,26 @@ +# Distribution project maintainers & reviewers +# +# See GOVERNANCE.md for maintainer versus reviewer roles +# +# MAINTAINERS (cncf-distribution-maintainers@lists.cncf.io) +# GitHub ID, Name, Email address +"chrispat","Chris Patterson","chrispat@github.com" +"clarkbw","Bryan Clark","clarkbw@github.com" +"corhere","Cory Snider","csnider@mirantis.com" +"deleteriousEffect","Hayley Swimelar","hswimelar@gitlab.com" +"heww","He Weiwei","hweiwei@vmware.com" +"joaodrp","João Pereira","jpereira@gitlab.com" +"justincormack","Justin Cormack","justin.cormack@docker.com" +"squizzi","Kyle Squizzato","ksquizzato@mirantis.com" +"milosgajdos","Milos Gajdos","milosthegajdos@gmail.com" +"sargun","Sargun Dhillon","sargun@sargun.me" +"wy65701436","Wang Yan","wangyan@vmware.com" +"stevelasker","Steve Lasker","steve.lasker@microsoft.com" +# +# REVIEWERS +# GitHub ID, Name, Email address +"dmcgowan","Derek McGowan","derek@mcgstyle.net" +"stevvooe","Stephen Day","stevvooe@gmail.com" +"thajeztah","Sebastiaan van Stijn","github@gone.nl" +"DavidSpek", "David van der Spek", "vanderspek.david@gmail.com" +"Jamstah", "James Hewitt", "james.hewitt@gmail.com" diff --git a/vendor/github.com/distribution/reference/Makefile b/vendor/github.com/distribution/reference/Makefile new file mode 100644 index 000000000..c78576b75 --- /dev/null +++ b/vendor/github.com/distribution/reference/Makefile @@ -0,0 +1,25 @@ +# Project packages. +PACKAGES=$(shell go list ./...) + +# Flags passed to `go test` +BUILDFLAGS ?= +TESTFLAGS ?= + +.PHONY: all build test coverage +.DEFAULT: all + +all: build + +build: ## no binaries to build, so just check compilation suceeds + go build ${BUILDFLAGS} ./... + +test: ## run tests + go test ${TESTFLAGS} ./... + +coverage: ## generate coverprofiles from the unit tests + rm -f coverage.txt + go test ${TESTFLAGS} -cover -coverprofile=cover.out ./... + +.PHONY: help +help: + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_\/%-]+:.*?##/ { printf " \033[36m%-27s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) diff --git a/vendor/github.com/distribution/reference/README.md b/vendor/github.com/distribution/reference/README.md new file mode 100644 index 000000000..e2531e49c --- /dev/null +++ b/vendor/github.com/distribution/reference/README.md @@ -0,0 +1,30 @@ +# Distribution reference + +Go library to handle references to container images. + + + +[![Build Status](https://github.com/distribution/reference/actions/workflows/test.yml/badge.svg?branch=main&event=push)](https://github.com/distribution/reference/actions?query=workflow%3ACI) +[![GoDoc](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/distribution/reference) +[![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE) +[![codecov](https://codecov.io/gh/distribution/reference/branch/main/graph/badge.svg)](https://codecov.io/gh/distribution/reference) +[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B162%2Fgithub.com%2Fdistribution%2Freference.svg?type=shield)](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fdistribution%2Freference?ref=badge_shield) + +This repository contains a library for handling refrences to container images held in container registries. Please see [godoc](https://pkg.go.dev/github.com/distribution/reference) for details. + +## Contribution + +Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute +issues, fixes, and patches to this project. + +## Communication + +For async communication and long running discussions please use issues and pull requests on the github repo. +This will be the best place to discuss design and implementation. + +For sync communication we have a #distribution channel in the [CNCF Slack](https://slack.cncf.io/) +that everyone is welcome to join and chat about development. + +## Licenses + +The distribution codebase is released under the [Apache 2.0 license](LICENSE). diff --git a/vendor/github.com/distribution/reference/SECURITY.md b/vendor/github.com/distribution/reference/SECURITY.md new file mode 100644 index 000000000..aaf983c0f --- /dev/null +++ b/vendor/github.com/distribution/reference/SECURITY.md @@ -0,0 +1,7 @@ +# Security Policy + +## Reporting a Vulnerability + +The maintainers take security seriously. If you discover a security issue, please bring it to their attention right away! + +Please DO NOT file a public issue, instead send your report privately to cncf-distribution-security@lists.cncf.io. diff --git a/vendor/github.com/distribution/reference/distribution-logo.svg b/vendor/github.com/distribution/reference/distribution-logo.svg new file mode 100644 index 000000000..cc9f4073b --- /dev/null +++ b/vendor/github.com/distribution/reference/distribution-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/vendor/github.com/docker/distribution/reference/helpers.go b/vendor/github.com/distribution/reference/helpers.go similarity index 94% rename from vendor/github.com/docker/distribution/reference/helpers.go rename to vendor/github.com/distribution/reference/helpers.go index 978df7eab..d10c7ef83 100644 --- a/vendor/github.com/docker/distribution/reference/helpers.go +++ b/vendor/github.com/distribution/reference/helpers.go @@ -32,7 +32,7 @@ func FamiliarString(ref Reference) string { } // FamiliarMatch reports whether ref matches the specified pattern. -// See https://godoc.org/path#Match for supported patterns. +// See [path.Match] for supported patterns. func FamiliarMatch(pattern string, ref Reference) (bool, error) { matched, err := path.Match(pattern, FamiliarString(ref)) if namedRef, isNamed := ref.(Named); isNamed && !matched { diff --git a/vendor/github.com/docker/distribution/reference/normalize.go b/vendor/github.com/distribution/reference/normalize.go similarity index 52% rename from vendor/github.com/docker/distribution/reference/normalize.go rename to vendor/github.com/distribution/reference/normalize.go index b3dfb7a6d..a30229d01 100644 --- a/vendor/github.com/docker/distribution/reference/normalize.go +++ b/vendor/github.com/distribution/reference/normalize.go @@ -1,19 +1,42 @@ package reference import ( - "errors" "fmt" "strings" - "github.com/docker/distribution/digestset" "github.com/opencontainers/go-digest" ) -var ( +const ( + // legacyDefaultDomain is the legacy domain for Docker Hub (which was + // originally named "the Docker Index"). This domain is still used for + // authentication and image search, which were part of the "v1" Docker + // registry specification. + // + // This domain will continue to be supported, but there are plans to consolidate + // legacy domains to new "canonical" domains. Once those domains are decided + // on, we must update the normalization functions, but preserve compatibility + // with existing installs, clients, and user configuration. legacyDefaultDomain = "index.docker.io" - defaultDomain = "docker.io" - officialRepoName = "library" - defaultTag = "latest" + + // defaultDomain is the default domain used for images on Docker Hub. + // It is used to normalize "familiar" names to canonical names, for example, + // to convert "ubuntu" to "docker.io/library/ubuntu:latest". + // + // Note that actual domain of Docker Hub's registry is registry-1.docker.io. + // This domain will continue to be supported, but there are plans to consolidate + // legacy domains to new "canonical" domains. Once those domains are decided + // on, we must update the normalization functions, but preserve compatibility + // with existing installs, clients, and user configuration. + defaultDomain = "docker.io" + + // officialRepoPrefix is the namespace used for official images on Docker Hub. + // It is used to normalize "familiar" names to canonical names, for example, + // to convert "ubuntu" to "docker.io/library/ubuntu:latest". + officialRepoPrefix = "library/" + + // defaultTag is the default tag if no tag is provided. + defaultTag = "latest" ) // normalizedNamed represents a name which has been @@ -35,14 +58,14 @@ func ParseNormalizedNamed(s string) (Named, error) { return nil, fmt.Errorf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings", s) } domain, remainder := splitDockerDomain(s) - var remoteName string + var remote string if tagSep := strings.IndexRune(remainder, ':'); tagSep > -1 { - remoteName = remainder[:tagSep] + remote = remainder[:tagSep] } else { - remoteName = remainder + remote = remainder } - if strings.ToLower(remoteName) != remoteName { - return nil, errors.New("invalid reference format: repository name must be lowercase") + if strings.ToLower(remote) != remote { + return nil, fmt.Errorf("invalid reference format: repository name (%s) must be lowercase", remote) } ref, err := Parse(domain + "/" + remainder) @@ -56,41 +79,53 @@ func ParseNormalizedNamed(s string) (Named, error) { return named, nil } -// ParseDockerRef normalizes the image reference following the docker convention. This is added -// mainly for backward compatibility. -// The reference returned can only be either tagged or digested. For reference contains both tag -// and digest, the function returns digested reference, e.g. docker.io/library/busybox:latest@ -// sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa will be returned as -// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa. +// namedTaggedDigested is a reference that has both a tag and a digest. +type namedTaggedDigested interface { + NamedTagged + Digested +} + +// ParseDockerRef normalizes the image reference following the docker convention, +// which allows for references to contain both a tag and a digest. It returns a +// reference that is either tagged or digested. For references containing both +// a tag and a digest, it returns a digested reference. For example, the following +// reference: +// +// docker.io/library/busybox:latest@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa +// +// Is returned as a digested reference (with the ":latest" tag removed): +// +// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa +// +// References that are already "tagged" or "digested" are returned unmodified: +// +// // Already a digested reference +// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa +// +// // Already a named reference +// docker.io/library/busybox:latest func ParseDockerRef(ref string) (Named, error) { named, err := ParseNormalizedNamed(ref) if err != nil { return nil, err } - if _, ok := named.(NamedTagged); ok { - if canonical, ok := named.(Canonical); ok { - // The reference is both tagged and digested, only - // return digested. - newNamed, err := WithName(canonical.Name()) - if err != nil { - return nil, err - } - newCanonical, err := WithDigest(newNamed, canonical.Digest()) - if err != nil { - return nil, err - } - return newCanonical, nil + if canonical, ok := named.(namedTaggedDigested); ok { + // The reference is both tagged and digested; only return digested. + newNamed, err := WithName(canonical.Name()) + if err != nil { + return nil, err } + return WithDigest(newNamed, canonical.Digest()) } return TagNameOnly(named), nil } -// splitDockerDomain splits a repository name to domain and remotename string. +// splitDockerDomain splits a repository name to domain and remote-name. // If no valid domain is found, the default domain is used. Repository name // needs to be already validated before. func splitDockerDomain(name string) (domain, remainder string) { i := strings.IndexRune(name, '/') - if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") { + if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != localhost && strings.ToLower(name[:i]) == name[:i]) { domain, remainder = defaultDomain, name } else { domain, remainder = name[:i], name[i+1:] @@ -99,13 +134,13 @@ func splitDockerDomain(name string) (domain, remainder string) { domain = defaultDomain } if domain == defaultDomain && !strings.ContainsRune(remainder, '/') { - remainder = officialRepoName + "/" + remainder + remainder = officialRepoPrefix + remainder } return } // familiarizeName returns a shortened version of the name familiar -// to to the Docker UI. Familiar names have the default domain +// to the Docker UI. Familiar names have the default domain // "docker.io" and "library/" repository prefix removed. // For example, "docker.io/library/redis" will have the familiar // name "redis" and "docker.io/dmcgowan/myapp" will be "dmcgowan/myapp". @@ -119,8 +154,15 @@ func familiarizeName(named namedRepository) repository { if repo.domain == defaultDomain { repo.domain = "" // Handle official repositories which have the pattern "library/" - if split := strings.Split(repo.path, "/"); len(split) == 2 && split[0] == officialRepoName { - repo.path = split[1] + if strings.HasPrefix(repo.path, officialRepoPrefix) { + // TODO(thaJeztah): this check may be too strict, as it assumes the + // "library/" namespace does not have nested namespaces. While this + // is true (currently), technically it would be possible for Docker + // Hub to use those (e.g. "library/distros/ubuntu:latest"). + // See https://github.com/distribution/distribution/pull/3769#issuecomment-1302031785. + if remainder := strings.TrimPrefix(repo.path, officialRepoPrefix); !strings.ContainsRune(remainder, '/') { + repo.path = remainder + } } } return repo @@ -180,20 +222,3 @@ func ParseAnyReference(ref string) (Reference, error) { return ParseNormalizedNamed(ref) } - -// ParseAnyReferenceWithSet parses a reference string as a possible short -// identifier to be matched in a digest set, a full digest, or familiar name. -func ParseAnyReferenceWithSet(ref string, ds *digestset.Set) (Reference, error) { - if ok := anchoredShortIdentifierRegexp.MatchString(ref); ok { - dgst, err := ds.Lookup(ref) - if err == nil { - return digestReference(dgst), nil - } - } else { - if dgst, err := digest.Parse(ref); err == nil { - return digestReference(dgst), nil - } - } - - return ParseNormalizedNamed(ref) -} diff --git a/vendor/github.com/docker/distribution/reference/reference.go b/vendor/github.com/distribution/reference/reference.go similarity index 93% rename from vendor/github.com/docker/distribution/reference/reference.go rename to vendor/github.com/distribution/reference/reference.go index b7cd00b0d..e98c44daa 100644 --- a/vendor/github.com/docker/distribution/reference/reference.go +++ b/vendor/github.com/distribution/reference/reference.go @@ -4,11 +4,14 @@ // Grammar // // reference := name [ ":" tag ] [ "@" digest ] -// name := [domain '/'] path-component ['/' path-component]* -// domain := domain-component ['.' domain-component]* [':' port-number] +// name := [domain '/'] remote-name +// domain := host [':' port-number] +// host := domain-name | IPv4address | \[ IPv6address \] ; rfc3986 appendix-A +// domain-name := domain-component ['.' domain-component]* // domain-component := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/ // port-number := /[0-9]+/ // path-component := alpha-numeric [separator alpha-numeric]* +// path (or "remote-name") := path-component ['/' path-component]* // alpha-numeric := /[a-z0-9]+/ // separator := /[_.]|__|[-]*/ // @@ -21,7 +24,6 @@ // digest-hex := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value // // identifier := /[a-f0-9]{64}/ -// short-identifier := /[a-f0-9]{6,64}/ package reference import ( @@ -145,7 +147,7 @@ type namedRepository interface { Path() string } -// Domain returns the domain part of the Named reference +// Domain returns the domain part of the [Named] reference. func Domain(named Named) string { if r, ok := named.(namedRepository); ok { return r.Domain() @@ -154,7 +156,7 @@ func Domain(named Named) string { return domain } -// Path returns the name without the domain part of the Named reference +// Path returns the name without the domain part of the [Named] reference. func Path(named Named) (name string) { if r, ok := named.(namedRepository); ok { return r.Path() @@ -175,7 +177,8 @@ func splitDomain(name string) (string, string) { // hostname and name string. If no valid hostname is // found, the hostname is empty and the full value // is returned as name -// DEPRECATED: Use Domain or Path +// +// Deprecated: Use [Domain] or [Path]. func SplitHostname(named Named) (string, string) { if r, ok := named.(namedRepository); ok { return r.Domain(), r.Path() @@ -185,7 +188,6 @@ func SplitHostname(named Named) (string, string) { // Parse parses s and returns a syntactically valid Reference. // If an error was encountered it is returned, along with a nil Reference. -// NOTE: Parse will not handle short digests. func Parse(s string) (Reference, error) { matches := ReferenceRegexp.FindStringSubmatch(s) if matches == nil { @@ -237,7 +239,6 @@ func Parse(s string) (Reference, error) { // the Named interface. The reference must have a name and be in the canonical // form, otherwise an error is returned. // If an error was encountered it is returned, along with a nil Reference. -// NOTE: ParseNamed will not handle short digests. func ParseNamed(s string) (Named, error) { named, err := ParseNormalizedNamed(s) if err != nil { @@ -320,11 +321,13 @@ func WithDigest(name Named, digest digest.Digest) (Canonical, error) { // TrimNamed removes any tag or digest from the named reference. func TrimNamed(ref Named) Named { - domain, path := SplitHostname(ref) - return repository{ - domain: domain, - path: path, + repo := repository{} + if r, ok := ref.(namedRepository); ok { + repo.domain, repo.path = r.Domain(), r.Path() + } else { + repo.domain, repo.path = splitDomain(ref.Name()) } + return repo } func getBestReferenceType(ref reference) Reference { diff --git a/vendor/github.com/distribution/reference/regexp.go b/vendor/github.com/distribution/reference/regexp.go new file mode 100644 index 000000000..65bc49d79 --- /dev/null +++ b/vendor/github.com/distribution/reference/regexp.go @@ -0,0 +1,163 @@ +package reference + +import ( + "regexp" + "strings" +) + +// DigestRegexp matches well-formed digests, including algorithm (e.g. "sha256:"). +var DigestRegexp = regexp.MustCompile(digestPat) + +// DomainRegexp matches hostname or IP-addresses, optionally including a port +// number. It defines the structure of potential domain components that may be +// part of image names. This is purposely a subset of what is allowed by DNS to +// ensure backwards compatibility with Docker image names. It may be a subset of +// DNS domain name, an IPv4 address in decimal format, or an IPv6 address between +// square brackets (excluding zone identifiers as defined by [RFC 6874] or special +// addresses such as IPv4-Mapped). +// +// [RFC 6874]: https://www.rfc-editor.org/rfc/rfc6874. +var DomainRegexp = regexp.MustCompile(domainAndPort) + +// IdentifierRegexp is the format for string identifier used as a +// content addressable identifier using sha256. These identifiers +// are like digests without the algorithm, since sha256 is used. +var IdentifierRegexp = regexp.MustCompile(identifier) + +// NameRegexp is the format for the name component of references, including +// an optional domain and port, but without tag or digest suffix. +var NameRegexp = regexp.MustCompile(namePat) + +// ReferenceRegexp is the full supported format of a reference. The regexp +// is anchored and has capturing groups for name, tag, and digest +// components. +var ReferenceRegexp = regexp.MustCompile(referencePat) + +// TagRegexp matches valid tag names. From [docker/docker:graph/tags.go]. +// +// [docker/docker:graph/tags.go]: https://github.com/moby/moby/blob/v1.6.0/graph/tags.go#L26-L28 +var TagRegexp = regexp.MustCompile(tag) + +const ( + // alphanumeric defines the alphanumeric atom, typically a + // component of names. This only allows lower case characters and digits. + alphanumeric = `[a-z0-9]+` + + // separator defines the separators allowed to be embedded in name + // components. This allows one period, one or two underscore and multiple + // dashes. Repeated dashes and underscores are intentionally treated + // differently. In order to support valid hostnames as name components, + // supporting repeated dash was added. Additionally double underscore is + // now allowed as a separator to loosen the restriction for previously + // supported names. + separator = `(?:[._]|__|[-]+)` + + // localhost is treated as a special value for domain-name. Any other + // domain-name without a "." or a ":port" are considered a path component. + localhost = `localhost` + + // domainNameComponent restricts the registry domain component of a + // repository name to start with a component as defined by DomainRegexp. + domainNameComponent = `(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])` + + // optionalPort matches an optional port-number including the port separator + // (e.g. ":80"). + optionalPort = `(?::[0-9]+)?` + + // tag matches valid tag names. From docker/docker:graph/tags.go. + tag = `[\w][\w.-]{0,127}` + + // digestPat matches well-formed digests, including algorithm (e.g. "sha256:"). + // + // TODO(thaJeztah): this should follow the same rules as https://pkg.go.dev/github.com/opencontainers/go-digest@v1.0.0#DigestRegexp + // so that go-digest defines the canonical format. Note that the go-digest is + // more relaxed: + // - it allows multiple algorithms (e.g. "sha256+b64:") to allow + // future expansion of supported algorithms. + // - it allows the "" value to use urlsafe base64 encoding as defined + // in [rfc4648, section 5]. + // + // [rfc4648, section 5]: https://www.rfc-editor.org/rfc/rfc4648#section-5. + digestPat = `[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}` + + // identifier is the format for a content addressable identifier using sha256. + // These identifiers are like digests without the algorithm, since sha256 is used. + identifier = `([a-f0-9]{64})` + + // ipv6address are enclosed between square brackets and may be represented + // in many ways, see rfc5952. Only IPv6 in compressed or uncompressed format + // are allowed, IPv6 zone identifiers (rfc6874) or Special addresses such as + // IPv4-Mapped are deliberately excluded. + ipv6address = `\[(?:[a-fA-F0-9:]+)\]` +) + +var ( + // domainName defines the structure of potential domain components + // that may be part of image names. This is purposely a subset of what is + // allowed by DNS to ensure backwards compatibility with Docker image + // names. This includes IPv4 addresses on decimal format. + domainName = domainNameComponent + anyTimes(`\.`+domainNameComponent) + + // host defines the structure of potential domains based on the URI + // Host subcomponent on rfc3986. It may be a subset of DNS domain name, + // or an IPv4 address in decimal format, or an IPv6 address between square + // brackets (excluding zone identifiers as defined by rfc6874 or special + // addresses such as IPv4-Mapped). + host = `(?:` + domainName + `|` + ipv6address + `)` + + // allowed by the URI Host subcomponent on rfc3986 to ensure backwards + // compatibility with Docker image names. + domainAndPort = host + optionalPort + + // anchoredTagRegexp matches valid tag names, anchored at the start and + // end of the matched string. + anchoredTagRegexp = regexp.MustCompile(anchored(tag)) + + // anchoredDigestRegexp matches valid digests, anchored at the start and + // end of the matched string. + anchoredDigestRegexp = regexp.MustCompile(anchored(digestPat)) + + // pathComponent restricts path-components to start with an alphanumeric + // character, with following parts able to be separated by a separator + // (one period, one or two underscore and multiple dashes). + pathComponent = alphanumeric + anyTimes(separator+alphanumeric) + + // remoteName matches the remote-name of a repository. It consists of one + // or more forward slash (/) delimited path-components: + // + // pathComponent[[/pathComponent] ...] // e.g., "library/ubuntu" + remoteName = pathComponent + anyTimes(`/`+pathComponent) + namePat = optional(domainAndPort+`/`) + remoteName + + // anchoredNameRegexp is used to parse a name value, capturing the + // domain and trailing components. + anchoredNameRegexp = regexp.MustCompile(anchored(optional(capture(domainAndPort), `/`), capture(remoteName))) + + referencePat = anchored(capture(namePat), optional(`:`, capture(tag)), optional(`@`, capture(digestPat))) + + // anchoredIdentifierRegexp is used to check or match an + // identifier value, anchored at start and end of string. + anchoredIdentifierRegexp = regexp.MustCompile(anchored(identifier)) +) + +// optional wraps the expression in a non-capturing group and makes the +// production optional. +func optional(res ...string) string { + return `(?:` + strings.Join(res, "") + `)?` +} + +// anyTimes wraps the expression in a non-capturing group that can occur +// any number of times. +func anyTimes(res ...string) string { + return `(?:` + strings.Join(res, "") + `)*` +} + +// capture wraps the expression in a capturing group. +func capture(res ...string) string { + return `(` + strings.Join(res, "") + `)` +} + +// anchored anchors the regular expression by adding start and end delimiters. +func anchored(res ...string) string { + return `^` + strings.Join(res, "") + `$` +} diff --git a/vendor/github.com/distribution/reference/sort.go b/vendor/github.com/distribution/reference/sort.go new file mode 100644 index 000000000..416c37b07 --- /dev/null +++ b/vendor/github.com/distribution/reference/sort.go @@ -0,0 +1,75 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package reference + +import ( + "sort" +) + +// Sort sorts string references preferring higher information references. +// +// The precedence is as follows: +// +// 1. [Named] + [Tagged] + [Digested] (e.g., "docker.io/library/busybox:latest@sha256:") +// 2. [Named] + [Tagged] (e.g., "docker.io/library/busybox:latest") +// 3. [Named] + [Digested] (e.g., "docker.io/library/busybo@sha256:") +// 4. [Named] (e.g., "docker.io/library/busybox") +// 5. [Digested] (e.g., "docker.io@sha256:") +// 6. Parse error +func Sort(references []string) []string { + var prefs []Reference + var bad []string + + for _, ref := range references { + pref, err := ParseAnyReference(ref) + if err != nil { + bad = append(bad, ref) + } else { + prefs = append(prefs, pref) + } + } + sort.Slice(prefs, func(a, b int) bool { + ar := refRank(prefs[a]) + br := refRank(prefs[b]) + if ar == br { + return prefs[a].String() < prefs[b].String() + } + return ar < br + }) + sort.Strings(bad) + var refs []string + for _, pref := range prefs { + refs = append(refs, pref.String()) + } + return append(refs, bad...) +} + +func refRank(ref Reference) uint8 { + if _, ok := ref.(Named); ok { + if _, ok = ref.(Tagged); ok { + if _, ok = ref.(Digested); ok { + return 1 + } + return 2 + } + if _, ok = ref.(Digested); ok { + return 3 + } + return 4 + } + return 5 +} diff --git a/vendor/github.com/docker/cli/cli/command/cli.go b/vendor/github.com/docker/cli/cli/command/cli.go index 2a61d5e48..1551c14da 100644 --- a/vendor/github.com/docker/cli/cli/command/cli.go +++ b/vendor/github.com/docker/cli/cli/command/cli.go @@ -8,7 +8,6 @@ import ( "path/filepath" "runtime" "strconv" - "strings" "sync" "time" @@ -48,9 +47,7 @@ type Streams interface { // Cli represents the docker command line client. type Cli interface { Client() client.APIClient - Out() *streams.Out - Err() io.Writer - In() *streams.In + Streams SetIn(in *streams.In) Apply(ops ...DockerCliOption) error ConfigFile() *configfile.ConfigFile @@ -191,7 +188,7 @@ func (cli *DockerCli) ManifestStore() manifeststore.Store { // RegistryClient returns a client for communicating with a Docker distribution // registry func (cli *DockerCli) RegistryClient(allowInsecure bool) registryclient.RegistryClient { - resolver := func(ctx context.Context, index *registry.IndexInfo) types.AuthConfig { + resolver := func(ctx context.Context, index *registry.IndexInfo) registry.AuthConfig { return ResolveAuthConfig(ctx, cli, index) } return registryclient.NewRegistryClient(resolver, UserAgent(), allowInsecure) @@ -329,13 +326,8 @@ func (cli *DockerCli) getInitTimeout() time.Duration { func (cli *DockerCli) initializeFromClient() { ctx := context.Background() - if !strings.HasPrefix(cli.dockerEndpoint.Host, "ssh://") { - // @FIXME context.WithTimeout doesn't work with connhelper / ssh connections - // time="2020-04-10T10:16:26Z" level=warning msg="commandConn.CloseWrite: commandconn: failed to wait: signal: killed" - var cancel func() - ctx, cancel = context.WithTimeout(ctx, cli.getInitTimeout()) - defer cancel() - } + ctx, cancel := context.WithTimeout(ctx, cli.getInitTimeout()) + defer cancel() ping, err := cli.client.Ping(ctx) if err != nil { @@ -383,7 +375,7 @@ func (cli *DockerCli) ContextStore() store.Store { // the "default" context is used if: // // - The "--host" option is set -// - The "DOCKER_HOST" ([DefaultContextName]) environment variable is set +// - The "DOCKER_HOST" ([client.EnvOverrideHost]) environment variable is set // to a non-empty value. // // In these cases, the default context is used, which uses the host as diff --git a/vendor/github.com/docker/cli/cli/command/events_utils.go b/vendor/github.com/docker/cli/cli/command/events_utils.go index 16d76892a..6a2907c53 100644 --- a/vendor/github.com/docker/cli/cli/command/events_utils.go +++ b/vendor/github.com/docker/cli/cli/command/events_utils.go @@ -3,28 +3,28 @@ package command import ( "sync" - eventtypes "github.com/docker/docker/api/types/events" + "github.com/docker/docker/api/types/events" "github.com/sirupsen/logrus" ) // EventHandler is abstract interface for user to customize // own handle functions of each type of events type EventHandler interface { - Handle(action string, h func(eventtypes.Message)) - Watch(c <-chan eventtypes.Message) + Handle(action string, h func(events.Message)) + Watch(c <-chan events.Message) } // InitEventHandler initializes and returns an EventHandler func InitEventHandler() EventHandler { - return &eventHandler{handlers: make(map[string]func(eventtypes.Message))} + return &eventHandler{handlers: make(map[string]func(events.Message))} } type eventHandler struct { - handlers map[string]func(eventtypes.Message) + handlers map[string]func(events.Message) mu sync.Mutex } -func (w *eventHandler) Handle(action string, h func(eventtypes.Message)) { +func (w *eventHandler) Handle(action string, h func(events.Message)) { w.mu.Lock() w.handlers[action] = h w.mu.Unlock() @@ -33,7 +33,7 @@ func (w *eventHandler) Handle(action string, h func(eventtypes.Message)) { // Watch ranges over the passed in event chan and processes the events based on the // handlers created for a given action. // To stop watching, close the event chan. -func (w *eventHandler) Watch(c <-chan eventtypes.Message) { +func (w *eventHandler) Watch(c <-chan events.Message) { for e := range c { w.mu.Lock() h, exists := w.handlers[e.Action] diff --git a/vendor/github.com/docker/cli/cli/command/registry.go b/vendor/github.com/docker/cli/cli/command/registry.go index 90cc08c53..95c16d7dc 100644 --- a/vendor/github.com/docker/cli/cli/command/registry.go +++ b/vendor/github.com/docker/cli/cli/command/registry.go @@ -3,8 +3,6 @@ package command import ( "bufio" "context" - "encoding/base64" - "encoding/json" "fmt" "io" "os" @@ -12,6 +10,7 @@ import ( "strings" configtypes "github.com/docker/cli/cli/config/types" + "github.com/docker/cli/cli/hints" "github.com/docker/cli/cli/streams" "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" @@ -21,20 +20,15 @@ import ( "github.com/pkg/errors" ) -// ElectAuthServer returns the default registry to use. -// -// Deprecated: use [registry.IndexServer] instead. -func ElectAuthServer(_ context.Context, _ Cli) string { - return registry.IndexServer -} +const patSuggest = "You can log in with your password or a Personal Access " + + "Token (PAT). Using a limited-scope PAT grants better security and is required " + + "for organizations using SSO. Learn more at https://docs.docker.com/go/access-tokens/" -// EncodeAuthToBase64 serializes the auth configuration as JSON base64 payload -func EncodeAuthToBase64(authConfig types.AuthConfig) (string, error) { - buf, err := json.Marshal(authConfig) - if err != nil { - return "", err - } - return base64.URLEncoding.EncodeToString(buf), nil +// EncodeAuthToBase64 serializes the auth configuration as JSON base64 payload. +// +// Deprecated: use [registrytypes.EncodeAuthConfig] instead. +func EncodeAuthToBase64(authConfig registrytypes.AuthConfig) (string, error) { + return registrytypes.EncodeAuthConfig(authConfig) } // RegistryAuthenticationPrivilegedFunc returns a RequestPrivilegeFunc from the specified registry index info @@ -52,7 +46,7 @@ func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInf if err != nil { return "", err } - return EncodeAuthToBase64(authConfig) + return registrytypes.EncodeAuthConfig(authConfig) } } @@ -62,19 +56,19 @@ func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInf // // It is similar to [registry.ResolveAuthConfig], but uses the credentials- // store, instead of looking up credentials from a map. -func ResolveAuthConfig(_ context.Context, cli Cli, index *registrytypes.IndexInfo) types.AuthConfig { +func ResolveAuthConfig(_ context.Context, cli Cli, index *registrytypes.IndexInfo) registrytypes.AuthConfig { configKey := index.Name if index.Official { configKey = registry.IndexServer } a, _ := cli.ConfigFile().GetAuthConfig(configKey) - return types.AuthConfig(a) + return registrytypes.AuthConfig(a) } // GetDefaultAuthConfig gets the default auth config given a serverAddress // If credentials for given serverAddress exists in the credential store, the configuration will be populated with values in it -func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, isDefaultRegistry bool) (types.AuthConfig, error) { +func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, isDefaultRegistry bool) (registrytypes.AuthConfig, error) { if !isDefaultRegistry { serverAddress = registry.ConvertToHostname(serverAddress) } @@ -83,20 +77,27 @@ func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, is if checkCredStore { authconfig, err = cli.ConfigFile().GetAuthConfig(serverAddress) if err != nil { - return types.AuthConfig{ + return registrytypes.AuthConfig{ ServerAddress: serverAddress, }, err } } authconfig.ServerAddress = serverAddress authconfig.IdentityToken = "" - res := types.AuthConfig(authconfig) + res := registrytypes.AuthConfig(authconfig) return res, nil } // ConfigureAuth handles prompting of user's username and password if needed -func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *types.AuthConfig, isDefaultRegistry bool) error { - // On Windows, force the use of the regular OS stdin stream. Fixes #14336/#14210 +func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *registrytypes.AuthConfig, isDefaultRegistry bool) error { + // On Windows, force the use of the regular OS stdin stream. + // + // See: + // - https://github.com/moby/moby/issues/14336 + // - https://github.com/moby/moby/issues/14210 + // - https://github.com/moby/moby/pull/17738 + // + // TODO(thaJeztah): we need to confirm if this special handling is still needed, as we may not be doing this in other places. if runtime.GOOS == "windows" { cli.SetIn(streams.NewIn(os.Stdin)) } @@ -117,11 +118,18 @@ func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *types.AuthCon if flUser = strings.TrimSpace(flUser); flUser == "" { if isDefaultRegistry { // if this is a default registry (docker hub), then display the following message. - fmt.Fprintln(cli.Out(), "Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.") + fmt.Fprintln(cli.Out(), "Log in with your Docker ID or email address to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com/ to create one.") + if hints.Enabled() { + fmt.Fprintln(cli.Out(), patSuggest) + fmt.Fprintln(cli.Out()) + } } promptWithDefault(cli.Out(), "Username", authconfig.Username) - flUser = readInput(cli.In(), cli.Out()) - flUser = strings.TrimSpace(flUser) + var err error + flUser, err = readInput(cli.In()) + if err != nil { + return err + } if flUser == "" { flUser = authconfig.Username } @@ -135,12 +143,15 @@ func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *types.AuthCon return err } fmt.Fprintf(cli.Out(), "Password: ") - term.DisableEcho(cli.In().FD(), oldState) - - flPassword = readInput(cli.In(), cli.Out()) + _ = term.DisableEcho(cli.In().FD(), oldState) + defer func() { + _ = term.RestoreTerminal(cli.In().FD(), oldState) + }() + flPassword, err = readInput(cli.In()) + if err != nil { + return err + } fmt.Fprint(cli.Out(), "\n") - - term.RestoreTerminal(cli.In().FD(), oldState) if flPassword == "" { return errors.Errorf("Error: Password Required") } @@ -152,14 +163,15 @@ func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *types.AuthCon return nil } -func readInput(in io.Reader, out io.Writer) string { - reader := bufio.NewReader(in) - line, _, err := reader.ReadLine() +// readInput reads, and returns user input from in. It tries to return a +// single line, not including the end-of-line bytes, and trims leading +// and trailing whitespace. +func readInput(in io.Reader) (string, error) { + line, _, err := bufio.NewReader(in).ReadLine() if err != nil { - fmt.Fprintln(out, err.Error()) - os.Exit(1) + return "", errors.Wrap(err, "error while reading input") } - return string(line) + return strings.TrimSpace(string(line)), nil } func promptWithDefault(out io.Writer, prompt string, configDefault string) { @@ -170,14 +182,19 @@ func promptWithDefault(out io.Writer, prompt string, configDefault string) { } } -// RetrieveAuthTokenFromImage retrieves an encoded auth token given a complete image +// RetrieveAuthTokenFromImage retrieves an encoded auth token given a complete +// image. The auth configuration is serialized as a base64url encoded RFC4648, +// section 5) JSON string for sending through the X-Registry-Auth header. +// +// For details on base64url encoding, see: +// - RFC4648, section 5: https://tools.ietf.org/html/rfc4648#section-5 func RetrieveAuthTokenFromImage(ctx context.Context, cli Cli, image string) (string, error) { // Retrieve encoded auth token from the image reference authConfig, err := resolveAuthConfigFromImage(ctx, cli, image) if err != nil { return "", err } - encodedAuth, err := EncodeAuthToBase64(authConfig) + encodedAuth, err := registrytypes.EncodeAuthConfig(authConfig) if err != nil { return "", err } @@ -185,14 +202,14 @@ func RetrieveAuthTokenFromImage(ctx context.Context, cli Cli, image string) (str } // resolveAuthConfigFromImage retrieves that AuthConfig using the image string -func resolveAuthConfigFromImage(ctx context.Context, cli Cli, image string) (types.AuthConfig, error) { +func resolveAuthConfigFromImage(ctx context.Context, cli Cli, image string) (registrytypes.AuthConfig, error) { registryRef, err := reference.ParseNormalizedNamed(image) if err != nil { - return types.AuthConfig{}, err + return registrytypes.AuthConfig{}, err } repoInfo, err := registry.ParseRepositoryInfo(registryRef) if err != nil { - return types.AuthConfig{}, err + return registrytypes.AuthConfig{}, err } return ResolveAuthConfig(ctx, cli, repoInfo.Index), nil } diff --git a/vendor/github.com/docker/cli/cli/command/streams.go b/vendor/github.com/docker/cli/cli/command/streams.go deleted file mode 100644 index 43dc6cd00..000000000 --- a/vendor/github.com/docker/cli/cli/command/streams.go +++ /dev/null @@ -1,32 +0,0 @@ -package command - -import ( - "io" - - "github.com/docker/cli/cli/streams" -) - -// InStream is an input stream used by the DockerCli to read user input -// -// Deprecated: Use [streams.In] instead. -type InStream = streams.In - -// OutStream is an output stream used by the DockerCli to write normal program -// output. -// -// Deprecated: Use [streams.Out] instead. -type OutStream = streams.Out - -// NewInStream returns a new [streams.In] from an [io.ReadCloser]. -// -// Deprecated: Use [streams.NewIn] instead. -func NewInStream(in io.ReadCloser) *streams.In { - return streams.NewIn(in) -} - -// NewOutStream returns a new [streams.Out] from an [io.Writer]. -// -// Deprecated: Use [streams.NewOut] instead. -func NewOutStream(out io.Writer) *streams.Out { - return streams.NewOut(out) -} diff --git a/vendor/github.com/docker/cli/cli/config/configfile/file.go b/vendor/github.com/docker/cli/cli/config/configfile/file.go index 609a88c27..442c31110 100644 --- a/vendor/github.com/docker/cli/cli/config/configfile/file.go +++ b/vendor/github.com/docker/cli/cli/config/configfile/file.go @@ -37,7 +37,6 @@ type ConfigFile struct { PruneFilters []string `json:"pruneFilters,omitempty"` Proxies map[string]ProxyConfig `json:"proxies,omitempty"` Experimental string `json:"experimental,omitempty"` - StackOrchestrator string `json:"stackOrchestrator,omitempty"` // Deprecated: swarm is now the default orchestrator, and this option is ignored. CurrentContext string `json:"currentContext,omitempty"` CLIPluginsExtraDirs []string `json:"cliPluginsExtraDirs,omitempty"` Plugins map[string]map[string]string `json:"plugins,omitempty"` @@ -95,6 +94,9 @@ func (configFile *ConfigFile) ContainsAuth() bool { // GetAuthConfigs returns the mapping of repo to auth configuration func (configFile *ConfigFile) GetAuthConfigs() map[string]types.AuthConfig { + if configFile.AuthConfigs == nil { + configFile.AuthConfigs = make(map[string]types.AuthConfig) + } return configFile.AuthConfigs } diff --git a/vendor/github.com/docker/cli/cli/config/credentials/file_store.go b/vendor/github.com/docker/cli/cli/config/credentials/file_store.go index de1c676e5..ea30fc300 100644 --- a/vendor/github.com/docker/cli/cli/config/credentials/file_store.go +++ b/vendor/github.com/docker/cli/cli/config/credentials/file_store.go @@ -52,7 +52,8 @@ func (c *fileStore) GetAll() (map[string]types.AuthConfig, error) { // Store saves the given credentials in the file store. func (c *fileStore) Store(authConfig types.AuthConfig) error { - c.file.GetAuthConfigs()[authConfig.ServerAddress] = authConfig + authConfigs := c.file.GetAuthConfigs() + authConfigs[authConfig.ServerAddress] = authConfig return c.file.Save() } diff --git a/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go b/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go index a0b035c92..835c4c48d 100644 --- a/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go +++ b/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go @@ -23,6 +23,7 @@ import ( "runtime" "strings" "sync" + "sync/atomic" "syscall" "time" @@ -32,7 +33,7 @@ import ( ) // New returns net.Conn -func New(ctx context.Context, cmd string, args ...string) (net.Conn, error) { +func New(_ context.Context, cmd string, args ...string) (net.Conn, error) { var ( c commandConn err error @@ -64,81 +65,68 @@ func New(ctx context.Context, cmd string, args ...string) (net.Conn, error) { // commandConn implements net.Conn type commandConn struct { - cmd *exec.Cmd - cmdExited bool - cmdWaitErr error - cmdMutex sync.Mutex - stdin io.WriteCloser - stdout io.ReadCloser - stderrMu sync.Mutex - stderr bytes.Buffer - stdioClosedMu sync.Mutex // for stdinClosed and stdoutClosed - stdinClosed bool - stdoutClosed bool - localAddr net.Addr - remoteAddr net.Addr + cmdMutex sync.Mutex // for cmd, cmdWaitErr + cmd *exec.Cmd + cmdWaitErr error + cmdExited atomic.Bool + stdin io.WriteCloser + stdout io.ReadCloser + stderrMu sync.Mutex // for stderr + stderr bytes.Buffer + stdinClosed atomic.Bool + stdoutClosed atomic.Bool + closing atomic.Bool + localAddr net.Addr + remoteAddr net.Addr } -// killIfStdioClosed kills the cmd if both stdin and stdout are closed. -func (c *commandConn) killIfStdioClosed() error { - c.stdioClosedMu.Lock() - stdioClosed := c.stdoutClosed && c.stdinClosed - c.stdioClosedMu.Unlock() - if !stdioClosed { - return nil +// kill terminates the process. On Windows it kills the process directly, +// whereas on other platforms, a SIGTERM is sent, before forcefully terminating +// the process after 3 seconds. +func (c *commandConn) kill() { + if c.cmdExited.Load() { + return } - return c.kill() -} - -// killAndWait tries sending SIGTERM to the process before sending SIGKILL. -func killAndWait(cmd *exec.Cmd) error { + c.cmdMutex.Lock() var werr error if runtime.GOOS != "windows" { werrCh := make(chan error) - go func() { werrCh <- cmd.Wait() }() - cmd.Process.Signal(syscall.SIGTERM) + go func() { werrCh <- c.cmd.Wait() }() + _ = c.cmd.Process.Signal(syscall.SIGTERM) select { case werr = <-werrCh: case <-time.After(3 * time.Second): - cmd.Process.Kill() + _ = c.cmd.Process.Kill() werr = <-werrCh } } else { - cmd.Process.Kill() - werr = cmd.Wait() + _ = c.cmd.Process.Kill() + werr = c.cmd.Wait() } - return werr + c.cmdWaitErr = werr + c.cmdMutex.Unlock() + c.cmdExited.Store(true) } -// kill returns nil if the command terminated, regardless to the exit status. -func (c *commandConn) kill() error { - var werr error - c.cmdMutex.Lock() - if c.cmdExited { - werr = c.cmdWaitErr - } else { - werr = killAndWait(c.cmd) - c.cmdWaitErr = werr - c.cmdExited = true - } - c.cmdMutex.Unlock() - if werr == nil { - return nil - } - wExitErr, ok := werr.(*exec.ExitError) - if ok { - if wExitErr.ProcessState.Exited() { - return nil - } +// handleEOF handles io.EOF errors while reading or writing from the underlying +// command pipes. +// +// When we've received an EOF we expect that the command will +// be terminated soon. As such, we call Wait() on the command +// and return EOF or the error depending on whether the command +// exited with an error. +// +// If Wait() does not return within 10s, an error is returned +func (c *commandConn) handleEOF(err error) error { + if err != io.EOF { + return err } - return errors.Wrapf(werr, "commandconn: failed to wait") -} -func (c *commandConn) onEOF(eof error) error { - // when we got EOF, the command is going to be terminated - var werr error c.cmdMutex.Lock() - if c.cmdExited { + defer c.cmdMutex.Unlock() + + var werr error + if c.cmdExited.Load() { werr = c.cmdWaitErr } else { werrCh := make(chan error) @@ -146,18 +134,17 @@ func (c *commandConn) onEOF(eof error) error { select { case werr = <-werrCh: c.cmdWaitErr = werr - c.cmdExited = true + c.cmdExited.Store(true) case <-time.After(10 * time.Second): - c.cmdMutex.Unlock() c.stderrMu.Lock() stderr := c.stderr.String() c.stderrMu.Unlock() - return errors.Errorf("command %v did not exit after %v: stderr=%q", c.cmd.Args, eof, stderr) + return errors.Errorf("command %v did not exit after %v: stderr=%q", c.cmd.Args, err, stderr) } } - c.cmdMutex.Unlock() + if werr == nil { - return eof + return err } c.stderrMu.Lock() stderr := c.stderr.String() @@ -166,71 +153,86 @@ func (c *commandConn) onEOF(eof error) error { } func ignorableCloseError(err error) bool { - errS := err.Error() - ss := []string{ - os.ErrClosed.Error(), + return strings.Contains(err.Error(), os.ErrClosed.Error()) +} + +func (c *commandConn) Read(p []byte) (int, error) { + n, err := c.stdout.Read(p) + // check after the call to Read, since + // it is blocking, and while waiting on it + // Close might get called + if c.closing.Load() { + // If we're currently closing the connection + // we don't want to call onEOF + return n, err } - for _, s := range ss { - if strings.Contains(errS, s) { - return true - } + + return n, c.handleEOF(err) +} + +func (c *commandConn) Write(p []byte) (int, error) { + n, err := c.stdin.Write(p) + // check after the call to Write, since + // it is blocking, and while waiting on it + // Close might get called + if c.closing.Load() { + // If we're currently closing the connection + // we don't want to call onEOF + return n, err } - return false + + return n, c.handleEOF(err) } +// CloseRead allows commandConn to implement halfCloser func (c *commandConn) CloseRead() error { // NOTE: maybe already closed here if err := c.stdout.Close(); err != nil && !ignorableCloseError(err) { - logrus.Warnf("commandConn.CloseRead: %v", err) + return err } - c.stdioClosedMu.Lock() - c.stdoutClosed = true - c.stdioClosedMu.Unlock() - if err := c.killIfStdioClosed(); err != nil { - logrus.Warnf("commandConn.CloseRead: %v", err) - } - return nil -} + c.stdoutClosed.Store(true) -func (c *commandConn) Read(p []byte) (int, error) { - n, err := c.stdout.Read(p) - if err == io.EOF { - err = c.onEOF(err) + if c.stdinClosed.Load() { + c.kill() } - return n, err + + return nil } +// CloseWrite allows commandConn to implement halfCloser func (c *commandConn) CloseWrite() error { // NOTE: maybe already closed here if err := c.stdin.Close(); err != nil && !ignorableCloseError(err) { - logrus.Warnf("commandConn.CloseWrite: %v", err) - } - c.stdioClosedMu.Lock() - c.stdinClosed = true - c.stdioClosedMu.Unlock() - if err := c.killIfStdioClosed(); err != nil { - logrus.Warnf("commandConn.CloseWrite: %v", err) + return err } - return nil -} + c.stdinClosed.Store(true) -func (c *commandConn) Write(p []byte) (int, error) { - n, err := c.stdin.Write(p) - if err == io.EOF { - err = c.onEOF(err) + if c.stdoutClosed.Load() { + c.kill() } - return n, err + return nil } +// Close is the net.Conn func that gets called +// by the transport when a dial is cancelled +// due to it's context timing out. Any blocked +// Read or Write calls will be unblocked and +// return errors. It will block until the underlying +// command has terminated. func (c *commandConn) Close() error { - var err error - if err = c.CloseRead(); err != nil { + c.closing.Store(true) + defer c.closing.Store(false) + + if err := c.CloseRead(); err != nil { logrus.Warnf("commandConn.Close: CloseRead: %v", err) + return err } - if err = c.CloseWrite(); err != nil { + if err := c.CloseWrite(); err != nil { logrus.Warnf("commandConn.Close: CloseWrite: %v", err) + return err } - return err + + return nil } func (c *commandConn) LocalAddr() net.Addr { diff --git a/vendor/github.com/docker/cli/cli/connhelper/connhelper.go b/vendor/github.com/docker/cli/cli/connhelper/connhelper.go index 9ac9d6744..b98d97c25 100644 --- a/vendor/github.com/docker/cli/cli/connhelper/connhelper.go +++ b/vendor/github.com/docker/cli/cli/connhelper/connhelper.go @@ -5,6 +5,7 @@ import ( "context" "net" "net/url" + "strings" "github.com/docker/cli/cli/connhelper/commandconn" "github.com/docker/cli/cli/connhelper/ssh" @@ -47,7 +48,13 @@ func getConnectionHelper(daemonURL string, sshFlags []string) (*ConnectionHelper } return &ConnectionHelper{ Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) { - return commandconn.New(ctx, "ssh", append(sshFlags, sp.Args("docker", "system", "dial-stdio")...)...) + args := []string{"docker"} + if sp.Path != "" { + args = append(args, "--host", "unix://"+sp.Path) + } + sshFlags = addSSHTimeout(sshFlags) + args = append(args, "system", "dial-stdio") + return commandconn.New(ctx, "ssh", append(sshFlags, sp.Args(args...)...)...) }, Host: "http://docker.example.com", }, nil @@ -66,3 +73,10 @@ func GetCommandConnectionHelper(cmd string, flags ...string) (*ConnectionHelper, Host: "http://docker.example.com", }, nil } + +func addSSHTimeout(sshFlags []string) []string { + if !strings.Contains(strings.Join(sshFlags, ""), "ConnectTimeout") { + sshFlags = append(sshFlags, "-o ConnectTimeout=30") + } + return sshFlags +} diff --git a/vendor/github.com/docker/cli/cli/connhelper/ssh/ssh.go b/vendor/github.com/docker/cli/cli/connhelper/ssh/ssh.go index bde01ae7f..fb4c91110 100644 --- a/vendor/github.com/docker/cli/cli/connhelper/ssh/ssh.go +++ b/vendor/github.com/docker/cli/cli/connhelper/ssh/ssh.go @@ -30,9 +30,7 @@ func ParseURL(daemonURL string) (*Spec, error) { return nil, errors.Errorf("no host specified") } sp.Port = u.Port() - if u.Path != "" { - return nil, errors.Errorf("extra path after the host: %q", u.Path) - } + sp.Path = u.Path if u.RawQuery != "" { return nil, errors.Errorf("extra query after the host: %q", u.RawQuery) } @@ -47,6 +45,7 @@ type Spec struct { User string Host string Port string + Path string } // Args returns args except "ssh" itself combined with optional additional command args diff --git a/vendor/github.com/docker/cli/cli/context/docker/load.go b/vendor/github.com/docker/cli/cli/context/docker/load.go index 09ec40505..76f6eaf30 100644 --- a/vendor/github.com/docker/cli/cli/context/docker/load.go +++ b/vendor/github.com/docker/cli/cli/context/docker/load.go @@ -25,12 +25,6 @@ type EndpointMeta = context.EndpointMetaBase type Endpoint struct { EndpointMeta TLSData *context.TLSData - - // Deprecated: Use of encrypted TLS private keys has been deprecated, and - // will be removed in a future release. Golang has deprecated support for - // legacy PEM encryption (as specified in RFC 1423), as it is insecure by - // design (see https://go-review.googlesource.com/c/go/+/264159). - TLSPassword string } // WithTLSData loads TLS materials for the endpoint diff --git a/vendor/github.com/docker/cli/cli/context/store/store.go b/vendor/github.com/docker/cli/cli/context/store/store.go index 037464bb1..710125230 100644 --- a/vendor/github.com/docker/cli/cli/context/store/store.go +++ b/vendor/github.com/docker/cli/cli/context/store/store.go @@ -494,20 +494,6 @@ func importEndpointTLS(tlsData *ContextTLSData, path string, data []byte) error return nil } -// IsErrContextDoesNotExist checks if the given error is a "context does not exist" condition. -// -// Deprecated: use github.com/docker/docker/errdefs.IsNotFound() -func IsErrContextDoesNotExist(err error) bool { - return errdefs.IsNotFound(err) -} - -// IsErrTLSDataDoesNotExist checks if the given error is a "context does not exist" condition -// -// Deprecated: use github.com/docker/docker/errdefs.IsNotFound() -func IsErrTLSDataDoesNotExist(err error) bool { - return errdefs.IsNotFound(err) -} - type contextdir string func contextdirOf(name string) contextdir { diff --git a/vendor/github.com/docker/cli/cli/flags/options.go b/vendor/github.com/docker/cli/cli/flags/options.go index cea0faf77..03c1f2db2 100644 --- a/vendor/github.com/docker/cli/cli/flags/options.go +++ b/vendor/github.com/docker/cli/cli/flags/options.go @@ -83,7 +83,7 @@ func (o *ClientOptions) InstallFlags(flags *pflag.FlagSet) { // opts.ValidateHost is not used here, so as to allow connection helpers hostOpt := opts.NewNamedListOptsRef("hosts", &o.Hosts, nil) - flags.VarP(hostOpt, "host", "H", "Daemon socket(s) to connect to") + flags.VarP(hostOpt, "host", "H", "Daemon socket to connect to") flags.StringVarP(&o.Context, "context", "c", "", `Name of the context to use to connect to the daemon (overrides `+client.EnvOverrideHost+` env var and default context set with "docker context use")`) } diff --git a/vendor/github.com/docker/cli/cli/flags/options_deprecated.go b/vendor/github.com/docker/cli/cli/flags/options_deprecated.go deleted file mode 100644 index 97fb7e4e6..000000000 --- a/vendor/github.com/docker/cli/cli/flags/options_deprecated.go +++ /dev/null @@ -1,11 +0,0 @@ -package flags - -// CommonOptions are options common to both the client and the daemon. -// -// Deprecated: use [ClientOptions]. -type CommonOptions = ClientOptions - -// NewCommonOptions returns a new CommonOptions -// -// Deprecated: use [NewClientOptions]. -var NewCommonOptions = NewClientOptions diff --git a/vendor/github.com/docker/cli/cli/hints/hints.go b/vendor/github.com/docker/cli/cli/hints/hints.go new file mode 100644 index 000000000..f99df8fda --- /dev/null +++ b/vendor/github.com/docker/cli/cli/hints/hints.go @@ -0,0 +1,18 @@ +package hints + +import ( + "os" + "strconv" +) + +// Enabled returns whether cli hints are enabled or not +func Enabled() bool { + if v := os.Getenv("DOCKER_CLI_HINTS"); v != "" { + enabled, err := strconv.ParseBool(v) + if err != nil { + return true + } + return enabled + } + return true +} diff --git a/vendor/github.com/docker/cli/cli/registry/client/client.go b/vendor/github.com/docker/cli/cli/registry/client/client.go index ba76a34fc..1c33a836f 100644 --- a/vendor/github.com/docker/cli/cli/registry/client/client.go +++ b/vendor/github.com/docker/cli/cli/registry/client/client.go @@ -7,10 +7,10 @@ import ( "strings" manifesttypes "github.com/docker/cli/cli/manifest/types" + "github.com/docker/cli/cli/trust" "github.com/docker/distribution" "github.com/docker/distribution/reference" distributionclient "github.com/docker/distribution/registry/client" - "github.com/docker/docker/api/types" registrytypes "github.com/docker/docker/api/types/registry" "github.com/opencontainers/go-digest" "github.com/pkg/errors" @@ -36,7 +36,7 @@ func NewRegistryClient(resolver AuthConfigResolver, userAgent string, insecure b } // AuthConfigResolver returns Auth Configuration for an index -type AuthConfigResolver func(ctx context.Context, index *registrytypes.IndexInfo) types.AuthConfig +type AuthConfigResolver func(ctx context.Context, index *registrytypes.IndexInfo) registrytypes.AuthConfig // PutManifestOptions is the data sent to push a manifest type PutManifestOptions struct { @@ -78,6 +78,7 @@ func (c *client) MountBlob(ctx context.Context, sourceRef reference.Canonical, t if err != nil { return err } + repoEndpoint.actions = trust.ActionsPushAndPull repo, err := c.getRepositoryForReference(ctx, targetRef, repoEndpoint) if err != nil { return err @@ -103,6 +104,7 @@ func (c *client) PutManifest(ctx context.Context, ref reference.Named, manifest return digest.Digest(""), err } + repoEndpoint.actions = trust.ActionsPushAndPull repo, err := c.getRepositoryForReference(ctx, ref, repoEndpoint) if err != nil { return digest.Digest(""), err @@ -152,7 +154,9 @@ func (c *client) getHTTPTransportForRepoEndpoint(ctx context.Context, repoEndpoi c.authConfigResolver(ctx, repoEndpoint.info.Index), repoEndpoint.endpoint, repoEndpoint.Name(), - c.userAgent) + c.userAgent, + repoEndpoint.actions, + ) return httpTransport, errors.Wrap(err, "failed to configure transport") } diff --git a/vendor/github.com/docker/cli/cli/registry/client/endpoint.go b/vendor/github.com/docker/cli/cli/registry/client/endpoint.go index f69c5c0dc..6d0e920c5 100644 --- a/vendor/github.com/docker/cli/cli/registry/client/endpoint.go +++ b/vendor/github.com/docker/cli/cli/registry/client/endpoint.go @@ -6,10 +6,11 @@ import ( "net/http" "time" + "github.com/docker/cli/cli/trust" "github.com/docker/distribution/reference" "github.com/docker/distribution/registry/client/auth" "github.com/docker/distribution/registry/client/transport" - authtypes "github.com/docker/docker/api/types" + registrytypes "github.com/docker/docker/api/types/registry" "github.com/docker/docker/registry" "github.com/pkg/errors" ) @@ -17,6 +18,7 @@ import ( type repositoryEndpoint struct { info *registry.RepositoryInfo endpoint registry.APIEndpoint + actions []string } // Name returns the repository name @@ -74,7 +76,7 @@ func getDefaultEndpointFromRepoInfo(repoInfo *registry.RepositoryInfo) (registry } // getHTTPTransport builds a transport for use in communicating with a registry -func getHTTPTransport(authConfig authtypes.AuthConfig, endpoint registry.APIEndpoint, repoName string, userAgent string) (http.RoundTripper, error) { +func getHTTPTransport(authConfig registrytypes.AuthConfig, endpoint registry.APIEndpoint, repoName, userAgent string, actions []string) (http.RoundTripper, error) { // get the http transport, this will be used in a client to upload manifest base := &http.Transport{ Proxy: http.ProxyFromEnvironment, @@ -98,8 +100,11 @@ func getHTTPTransport(authConfig authtypes.AuthConfig, endpoint registry.APIEndp passThruTokenHandler := &existingTokenHandler{token: authConfig.RegistryToken} modifiers = append(modifiers, auth.NewAuthorizer(challengeManager, passThruTokenHandler)) } else { + if len(actions) == 0 { + actions = trust.ActionsPullOnly + } creds := registry.NewStaticCredentialStore(&authConfig) - tokenHandler := auth.NewTokenHandler(authTransport, creds, repoName, "push", "pull") + tokenHandler := auth.NewTokenHandler(authTransport, creds, repoName, actions...) basicHandler := auth.NewBasicHandler(creds) modifiers = append(modifiers, auth.NewAuthorizer(challengeManager, tokenHandler, basicHandler)) } @@ -120,7 +125,7 @@ type existingTokenHandler struct { token string } -func (th *existingTokenHandler) AuthorizeRequest(req *http.Request, params map[string]string) error { +func (th *existingTokenHandler) AuthorizeRequest(req *http.Request, _ map[string]string) error { req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", th.token)) return nil } diff --git a/vendor/github.com/docker/cli/cli/registry/client/fetcher.go b/vendor/github.com/docker/cli/cli/registry/client/fetcher.go index acae274a4..3ce09d137 100644 --- a/vendor/github.com/docker/cli/cli/registry/client/fetcher.go +++ b/vendor/github.com/docker/cli/cli/registry/client/fetcher.go @@ -202,7 +202,8 @@ func pullManifestList(ctx context.Context, ref reference.Named, repo distributio } // Replace platform from config - imageManifest.Descriptor.Platform = types.OCIPlatform(&manifestDescriptor.Platform) + p := manifestDescriptor.Platform + imageManifest.Descriptor.Platform = types.OCIPlatform(&p) infos = append(infos, imageManifest) } @@ -242,11 +243,6 @@ func (c *client) iterateEndpoints(ctx context.Context, namedRef reference.Named, confirmedTLSRegistries := make(map[string]bool) for _, endpoint := range endpoints { - if endpoint.Version == registry.APIVersion1 { - logrus.Debugf("skipping v1 endpoint %s", endpoint.URL) - continue - } - if endpoint.URL.Scheme != "https" { if _, confirmedTLS := confirmedTLSRegistries[endpoint.URL.Host]; confirmedTLS { logrus.Debugf("skipping non-TLS endpoint %s for host/port that appears to use TLS", endpoint.URL) diff --git a/vendor/github.com/docker/cli/cli/streams/in.go b/vendor/github.com/docker/cli/cli/streams/in.go index 44b0de38b..1a10f7c83 100644 --- a/vendor/github.com/docker/cli/cli/streams/in.go +++ b/vendor/github.com/docker/cli/cli/streams/in.go @@ -9,38 +9,42 @@ import ( "github.com/moby/term" ) -// In is an input stream used by the DockerCli to read user input +// In is an input stream to read user input. It implements [io.ReadCloser] +// with additional utilities, such as putting the terminal in raw mode. type In struct { commonStream in io.ReadCloser } +// Read implements the [io.Reader] interface. func (i *In) Read(p []byte) (int, error) { return i.in.Read(p) } -// Close implements the Closer interface +// Close implements the [io.Closer] interface. func (i *In) Close() error { return i.in.Close() } -// SetRawTerminal sets raw mode on the input terminal +// SetRawTerminal sets raw mode on the input terminal. It is a no-op if In +// is not a TTY, or if the "NORAW" environment variable is set to a non-empty +// value. func (i *In) SetRawTerminal() (err error) { - if os.Getenv("NORAW") != "" || !i.commonStream.isTerminal { + if !i.isTerminal || os.Getenv("NORAW") != "" { return nil } - i.commonStream.state, err = term.SetRawTerminal(i.commonStream.fd) + i.state, err = term.SetRawTerminal(i.fd) return err } -// CheckTty checks if we are trying to attach to a container tty -// from a non-tty client input stream, and if so, returns an error. +// CheckTty checks if we are trying to attach to a container TTY +// from a non-TTY client input stream, and if so, returns an error. func (i *In) CheckTty(attachStdin, ttyMode bool) error { // In order to attach to a container tty, input stream for the client must // be a tty itself: redirecting or piping the client standard input is // incompatible with `docker run -t`, `docker exec -t` or `docker attach`. if ttyMode && attachStdin && !i.isTerminal { - eText := "the input device is not a TTY" + const eText = "the input device is not a TTY" if runtime.GOOS == "windows" { return errors.New(eText + ". If you are using mintty, try prefixing the command with 'winpty'") } @@ -49,8 +53,9 @@ func (i *In) CheckTty(attachStdin, ttyMode bool) error { return nil } -// NewIn returns a new In object from a ReadCloser +// NewIn returns a new [In] from an [io.ReadCloser]. func NewIn(in io.ReadCloser) *In { - fd, isTerminal := term.GetFdInfo(in) - return &In{commonStream: commonStream{fd: fd, isTerminal: isTerminal}, in: in} + i := &In{in: in} + i.fd, i.isTerminal = term.GetFdInfo(in) + return i } diff --git a/vendor/github.com/docker/cli/cli/streams/out.go b/vendor/github.com/docker/cli/cli/streams/out.go index 95e21464a..2383b0857 100644 --- a/vendor/github.com/docker/cli/cli/streams/out.go +++ b/vendor/github.com/docker/cli/cli/streams/out.go @@ -8,8 +8,9 @@ import ( "github.com/sirupsen/logrus" ) -// Out is an output stream used by the DockerCli to write normal program -// output. +// Out is an output stream to write normal program output. It implements +// an [io.Writer], with additional utilities for detecting whether a terminal +// is connected, getting the TTY size, and putting the terminal in raw mode. type Out struct { commonStream out io.Writer @@ -19,23 +20,29 @@ func (o *Out) Write(p []byte) (int, error) { return o.out.Write(p) } -// SetRawTerminal sets raw mode on the input terminal +// SetRawTerminal puts the output of the terminal connected to the stream +// into raw mode. +// +// On UNIX, this does nothing. On Windows, it disables LF -> CRLF/ translation. +// It is a no-op if Out is not a TTY, or if the "NORAW" environment variable is +// set to a non-empty value. func (o *Out) SetRawTerminal() (err error) { - if os.Getenv("NORAW") != "" || !o.commonStream.isTerminal { + if !o.isTerminal || os.Getenv("NORAW") != "" { return nil } - o.commonStream.state, err = term.SetRawTerminalOutput(o.commonStream.fd) + o.state, err = term.SetRawTerminalOutput(o.fd) return err } -// GetTtySize returns the height and width in characters of the tty -func (o *Out) GetTtySize() (uint, uint) { +// GetTtySize returns the height and width in characters of the TTY, or +// zero for both if no TTY is connected. +func (o *Out) GetTtySize() (height uint, width uint) { if !o.isTerminal { return 0, 0 } ws, err := term.GetWinsize(o.fd) if err != nil { - logrus.Debugf("Error getting size: %s", err) + logrus.WithError(err).Debug("Error getting TTY size") if ws == nil { return 0, 0 } @@ -43,8 +50,9 @@ func (o *Out) GetTtySize() (uint, uint) { return uint(ws.Height), uint(ws.Width) } -// NewOut returns a new Out object from a Writer +// NewOut returns a new [Out] from an [io.Writer]. func NewOut(out io.Writer) *Out { - fd, isTerminal := term.GetFdInfo(out) - return &Out{commonStream: commonStream{fd: fd, isTerminal: isTerminal}, out: out} + o := &Out{out: out} + o.fd, o.isTerminal = term.GetFdInfo(out) + return o } diff --git a/vendor/github.com/docker/cli/cli/streams/stream.go b/vendor/github.com/docker/cli/cli/streams/stream.go index 21f0e452e..54c9cda0b 100644 --- a/vendor/github.com/docker/cli/cli/streams/stream.go +++ b/vendor/github.com/docker/cli/cli/streams/stream.go @@ -4,31 +4,32 @@ import ( "github.com/moby/term" ) -// commonStream is an input stream used by the DockerCli to read user input type commonStream struct { fd uintptr isTerminal bool state *term.State } -// FD returns the file descriptor number for this stream +// FD returns the file descriptor number for this stream. func (s *commonStream) FD() uintptr { return s.fd } -// IsTerminal returns true if this stream is connected to a terminal +// IsTerminal returns true if this stream is connected to a terminal. func (s *commonStream) IsTerminal() bool { return s.isTerminal } -// RestoreTerminal restores normal mode to the terminal +// RestoreTerminal restores normal mode to the terminal. func (s *commonStream) RestoreTerminal() { if s.state != nil { - term.RestoreTerminal(s.fd, s.state) + _ = term.RestoreTerminal(s.fd, s.state) } } -// SetIsTerminal sets the boolean used for isTerminal +// SetIsTerminal overrides whether a terminal is connected. It is used to +// override this property in unit-tests, and should not be depended on for +// other purposes. func (s *commonStream) SetIsTerminal(isTerminal bool) { s.isTerminal = isTerminal } diff --git a/vendor/github.com/docker/cli/cli/trust/trust.go b/vendor/github.com/docker/cli/cli/trust/trust.go index 457f799fd..5a862e7f0 100644 --- a/vendor/github.com/docker/cli/cli/trust/trust.go +++ b/vendor/github.com/docker/cli/cli/trust/trust.go @@ -17,7 +17,6 @@ import ( "github.com/docker/distribution/registry/client/auth" "github.com/docker/distribution/registry/client/auth/challenge" "github.com/docker/distribution/registry/client/transport" - "github.com/docker/docker/api/types" registrytypes "github.com/docker/docker/api/types/registry" "github.com/docker/docker/registry" "github.com/docker/go-connections/tlsconfig" @@ -79,24 +78,23 @@ func Server(index *registrytypes.IndexInfo) (string, error) { } type simpleCredentialStore struct { - auth types.AuthConfig + auth registrytypes.AuthConfig } -func (scs simpleCredentialStore) Basic(u *url.URL) (string, string) { +func (scs simpleCredentialStore) Basic(*url.URL) (string, string) { return scs.auth.Username, scs.auth.Password } -func (scs simpleCredentialStore) RefreshToken(u *url.URL, service string) string { +func (scs simpleCredentialStore) RefreshToken(*url.URL, string) string { return scs.auth.IdentityToken } -func (scs simpleCredentialStore) SetRefreshToken(*url.URL, string, string) { -} +func (scs simpleCredentialStore) SetRefreshToken(*url.URL, string, string) {} // GetNotaryRepository returns a NotaryRepository which stores all the // information needed to operate on a notary repository. // It creates an HTTP transport providing authentication support. -func GetNotaryRepository(in io.Reader, out io.Writer, userAgent string, repoInfo *registry.RepositoryInfo, authConfig *types.AuthConfig, actions ...string) (client.Repository, error) { +func GetNotaryRepository(in io.Reader, out io.Writer, userAgent string, repoInfo *registry.RepositoryInfo, authConfig *registrytypes.AuthConfig, actions ...string) (client.Repository, error) { server, err := Server(repoInfo.Index) if err != nil { return nil, err @@ -160,7 +158,7 @@ func GetNotaryRepository(in io.Reader, out io.Writer, userAgent string, repoInfo scope := auth.RepositoryScope{ Repository: repoInfo.Name.Name(), Actions: actions, - Class: repoInfo.Class, + Class: repoInfo.Class, // TODO(thaJeztah): Class is no longer needed for plugins and can likely be removed; see https://github.com/docker/cli/pull/4114#discussion_r1145430825 } creds := simpleCredentialStore{auth: *authConfig} tokenHandlerOptions := auth.TokenHandlerOptions{ @@ -292,7 +290,7 @@ func GetSignableRoles(repo client.Repository, target *client.Target) ([]data.Rol // ImageRefAndAuth contains all reference information and the auth config for an image request type ImageRefAndAuth struct { original string - authConfig *types.AuthConfig + authConfig *registrytypes.AuthConfig reference reference.Named repoInfo *registry.RepositoryInfo tag string @@ -301,8 +299,8 @@ type ImageRefAndAuth struct { // GetImageReferencesAndAuth retrieves the necessary reference and auth information for an image name // as an ImageRefAndAuth struct -func GetImageReferencesAndAuth(ctx context.Context, rs registry.Service, - authResolver func(ctx context.Context, index *registrytypes.IndexInfo) types.AuthConfig, +func GetImageReferencesAndAuth(ctx context.Context, + authResolver func(ctx context.Context, index *registrytypes.IndexInfo) registrytypes.AuthConfig, imgName string, ) (ImageRefAndAuth, error) { ref, err := reference.ParseNormalizedNamed(imgName) @@ -311,13 +309,7 @@ func GetImageReferencesAndAuth(ctx context.Context, rs registry.Service, } // Resolve the Repository name from fqn to RepositoryInfo - var repoInfo *registry.RepositoryInfo - if rs != nil { - repoInfo, err = rs.ResolveRepository(ref) - } else { - repoInfo, err = registry.ParseRepositoryInfo(ref) - } - + repoInfo, err := registry.ParseRepositoryInfo(ref) if err != nil { return ImageRefAndAuth{}, err } @@ -356,7 +348,7 @@ func getDigest(ref reference.Named) digest.Digest { } // AuthConfig returns the auth information (username, etc) for a given ImageRefAndAuth -func (imgRefAuth *ImageRefAndAuth) AuthConfig() *types.AuthConfig { +func (imgRefAuth *ImageRefAndAuth) AuthConfig() *registrytypes.AuthConfig { return imgRefAuth.authConfig } diff --git a/vendor/github.com/docker/cli/opts/capabilities.go b/vendor/github.com/docker/cli/opts/capabilities.go index 8b5787037..82d071853 100644 --- a/vendor/github.com/docker/cli/opts/capabilities.go +++ b/vendor/github.com/docker/cli/opts/capabilities.go @@ -21,15 +21,15 @@ const ( // This function only handles rudimentary formatting; no validation is performed, // as the list of available capabilities can be updated over time, thus should be // handled by the daemon. -func NormalizeCapability(cap string) string { - cap = strings.ToUpper(strings.TrimSpace(cap)) - if cap == AllCapabilities || cap == ResetCapabilities { - return cap +func NormalizeCapability(capability string) string { + capability = strings.ToUpper(strings.TrimSpace(capability)) + if capability == AllCapabilities || capability == ResetCapabilities { + return capability } - if !strings.HasPrefix(cap, "CAP_") { - cap = "CAP_" + cap + if !strings.HasPrefix(capability, "CAP_") { + capability = "CAP_" + capability } - return cap + return capability } // CapabilitiesMap normalizes the given capabilities and converts them to a map. diff --git a/vendor/github.com/docker/distribution/.golangci.yml b/vendor/github.com/docker/distribution/.golangci.yml index 36c083b0f..61dd0e00e 100644 --- a/vendor/github.com/docker/distribution/.golangci.yml +++ b/vendor/github.com/docker/distribution/.golangci.yml @@ -1,7 +1,5 @@ linters: enable: - - structcheck - - varcheck - staticcheck - unconvert - gofmt @@ -14,6 +12,14 @@ linters: disable: - errcheck +linters-settings: + revive: + rules: + # TODO(thaJeztah): temporarily disabled the "unused-parameter" check. + # It produces many warnings, and some of those may need to be looked at. + - name: unused-parameter + disabled: true + run: deadline: 2m skip-dirs: diff --git a/vendor/github.com/docker/distribution/.mailmap b/vendor/github.com/docker/distribution/.mailmap index d94c3936e..d7b832d9e 100644 --- a/vendor/github.com/docker/distribution/.mailmap +++ b/vendor/github.com/docker/distribution/.mailmap @@ -49,3 +49,6 @@ Hayley Swimelar Jose D. Gomez R Shengjing Zhu Silvin Lubecki <31478878+silvin-lubecki@users.noreply.github.com> +James Hewitt +Marcus Pettersen Irgens +Ben Manuel diff --git a/vendor/github.com/docker/distribution/BUILDING.md b/vendor/github.com/docker/distribution/BUILDING.md index 2981d016b..4c43b03cb 100644 --- a/vendor/github.com/docker/distribution/BUILDING.md +++ b/vendor/github.com/docker/distribution/BUILDING.md @@ -114,4 +114,4 @@ the registry binary generated in the "./bin" directory: ### Optional build tags Optional [build tags](http://golang.org/pkg/go/build/) can be provided using -the environment variable `DOCKER_BUILDTAGS`. +the environment variable `BUILDTAGS`. diff --git a/vendor/github.com/docker/distribution/Dockerfile b/vendor/github.com/docker/distribution/Dockerfile index fb54b6813..ebd42c242 100644 --- a/vendor/github.com/docker/distribution/Dockerfile +++ b/vendor/github.com/docker/distribution/Dockerfile @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 -ARG GO_VERSION=1.19.9 -ARG ALPINE_VERSION=3.16 +ARG GO_VERSION=1.20.8 +ARG ALPINE_VERSION=3.18 ARG XX_VERSION=1.2.1 FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx @@ -22,12 +22,12 @@ RUN --mount=target=. \ FROM base AS build ARG TARGETPLATFORM ARG LDFLAGS="-s -w" -ARG BUILDTAGS="include_oss include_gcs" +ARG BUILDTAGS="include_oss,include_gcs" RUN --mount=type=bind,target=/go/src/github.com/docker/distribution,rw \ --mount=type=cache,target=/root/.cache/go-build \ --mount=target=/go/pkg/mod,type=cache \ --mount=type=bind,source=/tmp/.ldflags,target=/tmp/.ldflags,from=version \ - set -x ; xx-go build -trimpath -ldflags "$(cat /tmp/.ldflags) ${LDFLAGS}" -o /usr/bin/registry ./cmd/registry \ + set -x ; xx-go build -tags "${BUILDTAGS}" -trimpath -ldflags "$(cat /tmp/.ldflags) ${LDFLAGS}" -o /usr/bin/registry ./cmd/registry \ && xx-verify --static /usr/bin/registry FROM scratch AS binary diff --git a/vendor/github.com/docker/distribution/Makefile b/vendor/github.com/docker/distribution/Makefile index 75e118201..dcdbcb547 100644 --- a/vendor/github.com/docker/distribution/Makefile +++ b/vendor/github.com/docker/distribution/Makefile @@ -50,7 +50,7 @@ version/version.go: check: ## run all linters (TODO: enable "unused", "varcheck", "ineffassign", "unconvert", "staticheck", "goimports", "structcheck") @echo "$(WHALE) $@" - @GO111MODULE=off golangci-lint run + @GO111MODULE=off golangci-lint --build-tags "${BUILDTAGS}" run test: ## run tests, except integration test with test.short @echo "$(WHALE) $@" diff --git a/vendor/github.com/docker/distribution/blobs.go b/vendor/github.com/docker/distribution/blobs.go index 2a659eaa3..671372abf 100644 --- a/vendor/github.com/docker/distribution/blobs.go +++ b/vendor/github.com/docker/distribution/blobs.go @@ -8,7 +8,7 @@ import ( "net/http" "time" - "github.com/docker/distribution/reference" + "github.com/distribution/reference" "github.com/opencontainers/go-digest" v1 "github.com/opencontainers/image-spec/specs-go/v1" ) diff --git a/vendor/github.com/docker/distribution/reference/helpers_deprecated.go b/vendor/github.com/docker/distribution/reference/helpers_deprecated.go new file mode 100644 index 000000000..cbd119250 --- /dev/null +++ b/vendor/github.com/docker/distribution/reference/helpers_deprecated.go @@ -0,0 +1,34 @@ +package reference + +import "github.com/distribution/reference" + +// IsNameOnly returns true if reference only contains a repo name. +// +// Deprecated: use [reference.IsNameOnly]. +func IsNameOnly(ref reference.Named) bool { + return reference.IsNameOnly(ref) +} + +// FamiliarName returns the familiar name string +// for the given named, familiarizing if needed. +// +// Deprecated: use [reference.FamiliarName]. +func FamiliarName(ref reference.Named) string { + return reference.FamiliarName(ref) +} + +// FamiliarString returns the familiar string representation +// for the given reference, familiarizing if needed. +// +// Deprecated: use [reference.FamiliarString]. +func FamiliarString(ref reference.Reference) string { + return reference.FamiliarString(ref) +} + +// FamiliarMatch reports whether ref matches the specified pattern. +// See [path.Match] for supported patterns. +// +// Deprecated: use [reference.FamiliarMatch]. +func FamiliarMatch(pattern string, ref reference.Reference) (bool, error) { + return reference.FamiliarMatch(pattern, ref) +} diff --git a/vendor/github.com/docker/distribution/reference/normalize_deprecated.go b/vendor/github.com/docker/distribution/reference/normalize_deprecated.go new file mode 100644 index 000000000..1b4a459d7 --- /dev/null +++ b/vendor/github.com/docker/distribution/reference/normalize_deprecated.go @@ -0,0 +1,92 @@ +package reference + +import ( + "regexp" + + "github.com/distribution/reference" + "github.com/opencontainers/go-digest" + "github.com/opencontainers/go-digest/digestset" +) + +// ParseNormalizedNamed parses a string into a named reference +// transforming a familiar name from Docker UI to a fully +// qualified reference. If the value may be an identifier +// use ParseAnyReference. +// +// Deprecated: use [reference.ParseNormalizedNamed]. +func ParseNormalizedNamed(s string) (reference.Named, error) { + return reference.ParseNormalizedNamed(s) +} + +// ParseDockerRef normalizes the image reference following the docker convention, +// which allows for references to contain both a tag and a digest. +// +// Deprecated: use [reference.ParseDockerRef]. +func ParseDockerRef(ref string) (reference.Named, error) { + return reference.ParseDockerRef(ref) +} + +// TagNameOnly adds the default tag "latest" to a reference if it only has +// a repo name. +// +// Deprecated: use [reference.TagNameOnly]. +func TagNameOnly(ref reference.Named) reference.Named { + return reference.TagNameOnly(ref) +} + +// ParseAnyReference parses a reference string as a possible identifier, +// full digest, or familiar name. +// +// Deprecated: use [reference.ParseAnyReference]. +func ParseAnyReference(ref string) (reference.Reference, error) { + return reference.ParseAnyReference(ref) +} + +// Functions and types below have been removed in distribution v3 and +// have not been ported to github.com/distribution/reference. See +// https://github.com/distribution/distribution/pull/3774 + +var ( + // ShortIdentifierRegexp is the format used to represent a prefix + // of an identifier. A prefix may be used to match a sha256 identifier + // within a list of trusted identifiers. + // + // Deprecated: support for short-identifiers is deprecated, and will be removed in v3. + ShortIdentifierRegexp = regexp.MustCompile(shortIdentifier) + + shortIdentifier = `([a-f0-9]{6,64})` + + // anchoredShortIdentifierRegexp is used to check if a value + // is a possible identifier prefix, anchored at start and end + // of string. + anchoredShortIdentifierRegexp = regexp.MustCompile(`^` + shortIdentifier + `$`) +) + +type digestReference digest.Digest + +func (d digestReference) String() string { + return digest.Digest(d).String() +} + +func (d digestReference) Digest() digest.Digest { + return digest.Digest(d) +} + +// ParseAnyReferenceWithSet parses a reference string as a possible short +// identifier to be matched in a digest set, a full digest, or familiar name. +// +// Deprecated: support for short-identifiers is deprecated, and will be removed in v3. +func ParseAnyReferenceWithSet(ref string, ds *digestset.Set) (Reference, error) { + if ok := anchoredShortIdentifierRegexp.MatchString(ref); ok { + dgst, err := ds.Lookup(ref) + if err == nil { + return digestReference(dgst), nil + } + } else { + if dgst, err := digest.Parse(ref); err == nil { + return digestReference(dgst), nil + } + } + + return reference.ParseNormalizedNamed(ref) +} diff --git a/vendor/github.com/docker/distribution/reference/reference_deprecated.go b/vendor/github.com/docker/distribution/reference/reference_deprecated.go new file mode 100644 index 000000000..5b732498e --- /dev/null +++ b/vendor/github.com/docker/distribution/reference/reference_deprecated.go @@ -0,0 +1,172 @@ +// Package reference is deprecated, and has moved to github.com/distribution/reference. +// +// Deprecated: use github.com/distribution/reference instead. +package reference + +import ( + "github.com/distribution/reference" + "github.com/opencontainers/go-digest" +) + +const ( + // NameTotalLengthMax is the maximum total number of characters in a repository name. + // + // Deprecated: use [reference.NameTotalLengthMax]. + NameTotalLengthMax = reference.NameTotalLengthMax +) + +var ( + // ErrReferenceInvalidFormat represents an error while trying to parse a string as a reference. + // + // Deprecated: use [reference.ErrReferenceInvalidFormat]. + ErrReferenceInvalidFormat = reference.ErrReferenceInvalidFormat + + // ErrTagInvalidFormat represents an error while trying to parse a string as a tag. + // + // Deprecated: use [reference.ErrTagInvalidFormat]. + ErrTagInvalidFormat = reference.ErrTagInvalidFormat + + // ErrDigestInvalidFormat represents an error while trying to parse a string as a tag. + // + // Deprecated: use [reference.ErrDigestInvalidFormat]. + ErrDigestInvalidFormat = reference.ErrDigestInvalidFormat + + // ErrNameContainsUppercase is returned for invalid repository names that contain uppercase characters. + // + // Deprecated: use [reference.ErrNameContainsUppercase]. + ErrNameContainsUppercase = reference.ErrNameContainsUppercase + + // ErrNameEmpty is returned for empty, invalid repository names. + // + // Deprecated: use [reference.ErrNameEmpty]. + ErrNameEmpty = reference.ErrNameEmpty + + // ErrNameTooLong is returned when a repository name is longer than NameTotalLengthMax. + // + // Deprecated: use [reference.ErrNameTooLong]. + ErrNameTooLong = reference.ErrNameTooLong + + // ErrNameNotCanonical is returned when a name is not canonical. + // + // Deprecated: use [reference.ErrNameNotCanonical]. + ErrNameNotCanonical = reference.ErrNameNotCanonical +) + +// Reference is an opaque object reference identifier that may include +// modifiers such as a hostname, name, tag, and digest. +// +// Deprecated: use [reference.Reference]. +type Reference = reference.Reference + +// Field provides a wrapper type for resolving correct reference types when +// working with encoding. +// +// Deprecated: use [reference.Field]. +type Field = reference.Field + +// AsField wraps a reference in a Field for encoding. +// +// Deprecated: use [reference.AsField]. +func AsField(ref reference.Reference) reference.Field { + return reference.AsField(ref) +} + +// Named is an object with a full name +// +// Deprecated: use [reference.Named]. +type Named = reference.Named + +// Tagged is an object which has a tag +// +// Deprecated: use [reference.Tagged]. +type Tagged = reference.Tagged + +// NamedTagged is an object including a name and tag. +// +// Deprecated: use [reference.NamedTagged]. +type NamedTagged reference.NamedTagged + +// Digested is an object which has a digest +// in which it can be referenced by +// +// Deprecated: use [reference.Digested]. +type Digested reference.Digested + +// Canonical reference is an object with a fully unique +// name including a name with domain and digest +// +// Deprecated: use [reference.Canonical]. +type Canonical reference.Canonical + +// Domain returns the domain part of the [Named] reference. +// +// Deprecated: use [reference.Domain]. +func Domain(named reference.Named) string { + return reference.Domain(named) +} + +// Path returns the name without the domain part of the [Named] reference. +// +// Deprecated: use [reference.Path]. +func Path(named reference.Named) (name string) { + return reference.Path(named) +} + +// SplitHostname splits a named reference into a +// hostname and name string. If no valid hostname is +// found, the hostname is empty and the full value +// is returned as name +// +// Deprecated: Use [reference.Domain] or [reference.Path]. +func SplitHostname(named reference.Named) (string, string) { + return reference.SplitHostname(named) +} + +// Parse parses s and returns a syntactically valid Reference. +// If an error was encountered it is returned, along with a nil Reference. +// +// Deprecated: use [reference.Parse]. +func Parse(s string) (reference.Reference, error) { + return reference.Parse(s) +} + +// ParseNamed parses s and returns a syntactically valid reference implementing +// the Named interface. The reference must have a name and be in the canonical +// form, otherwise an error is returned. +// If an error was encountered it is returned, along with a nil Reference. +// +// Deprecated: use [reference.ParseNamed]. +func ParseNamed(s string) (reference.Named, error) { + return reference.ParseNamed(s) +} + +// WithName returns a named object representing the given string. If the input +// is invalid ErrReferenceInvalidFormat will be returned. +// +// Deprecated: use [reference.WithName]. +func WithName(name string) (reference.Named, error) { + return reference.WithName(name) +} + +// WithTag combines the name from "name" and the tag from "tag" to form a +// reference incorporating both the name and the tag. +// +// Deprecated: use [reference.WithTag]. +func WithTag(name reference.Named, tag string) (reference.NamedTagged, error) { + return reference.WithTag(name, tag) +} + +// WithDigest combines the name from "name" and the digest from "digest" to form +// a reference incorporating both the name and the digest. +// +// Deprecated: use [reference.WithDigest]. +func WithDigest(name reference.Named, digest digest.Digest) (reference.Canonical, error) { + return reference.WithDigest(name, digest) +} + +// TrimNamed removes any tag or digest from the named reference. +// +// Deprecated: use [reference.TrimNamed]. +func TrimNamed(ref reference.Named) reference.Named { + return reference.TrimNamed(ref) +} diff --git a/vendor/github.com/docker/distribution/reference/regexp.go b/vendor/github.com/docker/distribution/reference/regexp.go deleted file mode 100644 index 786034932..000000000 --- a/vendor/github.com/docker/distribution/reference/regexp.go +++ /dev/null @@ -1,143 +0,0 @@ -package reference - -import "regexp" - -var ( - // alphaNumericRegexp defines the alpha numeric atom, typically a - // component of names. This only allows lower case characters and digits. - alphaNumericRegexp = match(`[a-z0-9]+`) - - // separatorRegexp defines the separators allowed to be embedded in name - // components. This allow one period, one or two underscore and multiple - // dashes. - separatorRegexp = match(`(?:[._]|__|[-]*)`) - - // nameComponentRegexp restricts registry path component names to start - // with at least one letter or number, with following parts able to be - // separated by one period, one or two underscore and multiple dashes. - nameComponentRegexp = expression( - alphaNumericRegexp, - optional(repeated(separatorRegexp, alphaNumericRegexp))) - - // domainComponentRegexp restricts the registry domain component of a - // repository name to start with a component as defined by DomainRegexp - // and followed by an optional port. - domainComponentRegexp = match(`(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`) - - // DomainRegexp defines the structure of potential domain components - // that may be part of image names. This is purposely a subset of what is - // allowed by DNS to ensure backwards compatibility with Docker image - // names. - DomainRegexp = expression( - domainComponentRegexp, - optional(repeated(literal(`.`), domainComponentRegexp)), - optional(literal(`:`), match(`[0-9]+`))) - - // TagRegexp matches valid tag names. From docker/docker:graph/tags.go. - TagRegexp = match(`[\w][\w.-]{0,127}`) - - // anchoredTagRegexp matches valid tag names, anchored at the start and - // end of the matched string. - anchoredTagRegexp = anchored(TagRegexp) - - // DigestRegexp matches valid digests. - DigestRegexp = match(`[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}`) - - // anchoredDigestRegexp matches valid digests, anchored at the start and - // end of the matched string. - anchoredDigestRegexp = anchored(DigestRegexp) - - // NameRegexp is the format for the name component of references. The - // regexp has capturing groups for the domain and name part omitting - // the separating forward slash from either. - NameRegexp = expression( - optional(DomainRegexp, literal(`/`)), - nameComponentRegexp, - optional(repeated(literal(`/`), nameComponentRegexp))) - - // anchoredNameRegexp is used to parse a name value, capturing the - // domain and trailing components. - anchoredNameRegexp = anchored( - optional(capture(DomainRegexp), literal(`/`)), - capture(nameComponentRegexp, - optional(repeated(literal(`/`), nameComponentRegexp)))) - - // ReferenceRegexp is the full supported format of a reference. The regexp - // is anchored and has capturing groups for name, tag, and digest - // components. - ReferenceRegexp = anchored(capture(NameRegexp), - optional(literal(":"), capture(TagRegexp)), - optional(literal("@"), capture(DigestRegexp))) - - // IdentifierRegexp is the format for string identifier used as a - // content addressable identifier using sha256. These identifiers - // are like digests without the algorithm, since sha256 is used. - IdentifierRegexp = match(`([a-f0-9]{64})`) - - // ShortIdentifierRegexp is the format used to represent a prefix - // of an identifier. A prefix may be used to match a sha256 identifier - // within a list of trusted identifiers. - ShortIdentifierRegexp = match(`([a-f0-9]{6,64})`) - - // anchoredIdentifierRegexp is used to check or match an - // identifier value, anchored at start and end of string. - anchoredIdentifierRegexp = anchored(IdentifierRegexp) - - // anchoredShortIdentifierRegexp is used to check if a value - // is a possible identifier prefix, anchored at start and end - // of string. - anchoredShortIdentifierRegexp = anchored(ShortIdentifierRegexp) -) - -// match compiles the string to a regular expression. -var match = regexp.MustCompile - -// literal compiles s into a literal regular expression, escaping any regexp -// reserved characters. -func literal(s string) *regexp.Regexp { - re := match(regexp.QuoteMeta(s)) - - if _, complete := re.LiteralPrefix(); !complete { - panic("must be a literal") - } - - return re -} - -// expression defines a full expression, where each regular expression must -// follow the previous. -func expression(res ...*regexp.Regexp) *regexp.Regexp { - var s string - for _, re := range res { - s += re.String() - } - - return match(s) -} - -// optional wraps the expression in a non-capturing group and makes the -// production optional. -func optional(res ...*regexp.Regexp) *regexp.Regexp { - return match(group(expression(res...)).String() + `?`) -} - -// repeated wraps the regexp in a non-capturing group to get one or more -// matches. -func repeated(res ...*regexp.Regexp) *regexp.Regexp { - return match(group(expression(res...)).String() + `+`) -} - -// group wraps the regexp in a non-capturing group. -func group(res ...*regexp.Regexp) *regexp.Regexp { - return match(`(?:` + expression(res...).String() + `)`) -} - -// capture wraps the expression in a capturing group. -func capture(res ...*regexp.Regexp) *regexp.Regexp { - return match(`(` + expression(res...).String() + `)`) -} - -// anchored anchors the regular expression by adding start and end delimiters. -func anchored(res ...*regexp.Regexp) *regexp.Regexp { - return match(`^` + expression(res...).String() + `$`) -} diff --git a/vendor/github.com/docker/distribution/reference/regexp_deprecated.go b/vendor/github.com/docker/distribution/reference/regexp_deprecated.go new file mode 100644 index 000000000..4b9c1b58e --- /dev/null +++ b/vendor/github.com/docker/distribution/reference/regexp_deprecated.go @@ -0,0 +1,50 @@ +package reference + +import ( + "github.com/distribution/reference" +) + +// DigestRegexp matches well-formed digests, including algorithm (e.g. "sha256:"). +// +// Deprecated: use [reference.DigestRegexp]. +var DigestRegexp = reference.DigestRegexp + +// DomainRegexp matches hostname or IP-addresses, optionally including a port +// number. It defines the structure of potential domain components that may be +// part of image names. This is purposely a subset of what is allowed by DNS to +// ensure backwards compatibility with Docker image names. It may be a subset of +// DNS domain name, an IPv4 address in decimal format, or an IPv6 address between +// square brackets (excluding zone identifiers as defined by [RFC 6874] or special +// addresses such as IPv4-Mapped). +// +// Deprecated: use [reference.DomainRegexp]. +// +// [RFC 6874]: https://www.rfc-editor.org/rfc/rfc6874. +var DomainRegexp = reference.DigestRegexp + +// IdentifierRegexp is the format for string identifier used as a +// content addressable identifier using sha256. These identifiers +// are like digests without the algorithm, since sha256 is used. +// +// Deprecated: use [reference.IdentifierRegexp]. +var IdentifierRegexp = reference.IdentifierRegexp + +// NameRegexp is the format for the name component of references, including +// an optional domain and port, but without tag or digest suffix. +// +// Deprecated: use [reference.NameRegexp]. +var NameRegexp = reference.NameRegexp + +// ReferenceRegexp is the full supported format of a reference. The regexp +// is anchored and has capturing groups for name, tag, and digest +// components. +// +// Deprecated: use [reference.ReferenceRegexp]. +var ReferenceRegexp = reference.ReferenceRegexp + +// TagRegexp matches valid tag names. From [docker/docker:graph/tags.go]. +// +// Deprecated: use [reference.TagRegexp]. +// +// [docker/docker:graph/tags.go]: https://github.com/moby/moby/blob/v1.6.0/graph/tags.go#L26-L28 +var TagRegexp = reference.TagRegexp diff --git a/vendor/github.com/docker/distribution/reference/sort_deprecated.go b/vendor/github.com/docker/distribution/reference/sort_deprecated.go new file mode 100644 index 000000000..a73251b6f --- /dev/null +++ b/vendor/github.com/docker/distribution/reference/sort_deprecated.go @@ -0,0 +1,10 @@ +package reference + +import "github.com/distribution/reference" + +// Sort sorts string references preferring higher information references. +// +// Deprecated: use [reference.Sort]. +func Sort(references []string) []string { + return reference.Sort(references) +} diff --git a/vendor/github.com/docker/distribution/registry.go b/vendor/github.com/docker/distribution/registry.go index 6c3210989..d0deee65d 100644 --- a/vendor/github.com/docker/distribution/registry.go +++ b/vendor/github.com/docker/distribution/registry.go @@ -3,7 +3,7 @@ package distribution import ( "context" - "github.com/docker/distribution/reference" + "github.com/distribution/reference" ) // Scope defines the set of items that match a namespace. diff --git a/vendor/github.com/docker/distribution/registry/api/v2/descriptors.go b/vendor/github.com/docker/distribution/registry/api/v2/descriptors.go index c3bf90f71..7fceefbc6 100644 --- a/vendor/github.com/docker/distribution/registry/api/v2/descriptors.go +++ b/vendor/github.com/docker/distribution/registry/api/v2/descriptors.go @@ -4,7 +4,7 @@ import ( "net/http" "regexp" - "github.com/docker/distribution/reference" + "github.com/distribution/reference" "github.com/docker/distribution/registry/api/errcode" "github.com/opencontainers/go-digest" ) diff --git a/vendor/github.com/docker/distribution/registry/api/v2/urls.go b/vendor/github.com/docker/distribution/registry/api/v2/urls.go index 3c3ec9893..ab6406335 100644 --- a/vendor/github.com/docker/distribution/registry/api/v2/urls.go +++ b/vendor/github.com/docker/distribution/registry/api/v2/urls.go @@ -6,7 +6,7 @@ import ( "net/url" "strings" - "github.com/docker/distribution/reference" + "github.com/distribution/reference" "github.com/gorilla/mux" ) diff --git a/vendor/github.com/docker/distribution/registry/client/blob_writer.go b/vendor/github.com/docker/distribution/registry/client/blob_writer.go index 695bf852f..dac030c73 100644 --- a/vendor/github.com/docker/distribution/registry/client/blob_writer.go +++ b/vendor/github.com/docker/distribution/registry/client/blob_writer.go @@ -42,6 +42,8 @@ func (hbu *httpBlobUpload) ReadFrom(r io.Reader) (n int64, err error) { } defer req.Body.Close() + req.Header.Set("Content-Type", "application/octet-stream") + resp, err := hbu.client.Do(req) if err != nil { return 0, err diff --git a/vendor/github.com/docker/distribution/registry/client/errors.go b/vendor/github.com/docker/distribution/registry/client/errors.go index 024df43dd..ce9902034 100644 --- a/vendor/github.com/docker/distribution/registry/client/errors.go +++ b/vendor/github.com/docker/distribution/registry/client/errors.go @@ -4,8 +4,8 @@ import ( "encoding/json" "errors" "fmt" - "io" "io/ioutil" + "mime" "net/http" "github.com/docker/distribution/registry/api/errcode" @@ -38,13 +38,29 @@ func (e *UnexpectedHTTPResponseError) Error() string { return fmt.Sprintf("error parsing HTTP %d response body: %s: %q", e.StatusCode, e.ParseErr.Error(), string(e.Response)) } -func parseHTTPErrorResponse(statusCode int, r io.Reader) error { +func parseHTTPErrorResponse(resp *http.Response) error { var errors errcode.Errors - body, err := ioutil.ReadAll(r) + body, err := ioutil.ReadAll(resp.Body) if err != nil { return err } + statusCode := resp.StatusCode + ctHeader := resp.Header.Get("Content-Type") + + if ctHeader == "" { + return makeError(statusCode, string(body)) + } + + contentType, _, err := mime.ParseMediaType(ctHeader) + if err != nil { + return fmt.Errorf("failed parsing content-type: %w", err) + } + + if contentType != "application/json" && contentType != "application/vnd.api+json" { + return makeError(statusCode, string(body)) + } + // For backward compatibility, handle irregularly formatted // messages that contain a "details" field. var detailsErr struct { @@ -52,16 +68,7 @@ func parseHTTPErrorResponse(statusCode int, r io.Reader) error { } err = json.Unmarshal(body, &detailsErr) if err == nil && detailsErr.Details != "" { - switch statusCode { - case http.StatusUnauthorized: - return errcode.ErrorCodeUnauthorized.WithMessage(detailsErr.Details) - case http.StatusForbidden: - return errcode.ErrorCodeDenied.WithMessage(detailsErr.Details) - case http.StatusTooManyRequests: - return errcode.ErrorCodeTooManyRequests.WithMessage(detailsErr.Details) - default: - return errcode.ErrorCodeUnknown.WithMessage(detailsErr.Details) - } + return makeError(statusCode, detailsErr.Details) } if err := json.Unmarshal(body, &errors); err != nil { @@ -85,6 +92,19 @@ func parseHTTPErrorResponse(statusCode int, r io.Reader) error { return errors } +func makeError(statusCode int, details string) error { + switch statusCode { + case http.StatusUnauthorized: + return errcode.ErrorCodeUnauthorized.WithMessage(details) + case http.StatusForbidden: + return errcode.ErrorCodeDenied.WithMessage(details) + case http.StatusTooManyRequests: + return errcode.ErrorCodeTooManyRequests.WithMessage(details) + default: + return errcode.ErrorCodeUnknown.WithMessage(details) + } +} + func makeErrorList(err error) []error { if errL, ok := err.(errcode.Errors); ok { return []error(errL) @@ -121,11 +141,10 @@ func HandleErrorResponse(resp *http.Response) error { } else { err.Message = err.Code.Message() } - - return mergeErrors(err, parseHTTPErrorResponse(resp.StatusCode, resp.Body)) + return mergeErrors(err, parseHTTPErrorResponse(resp)) } } - err := parseHTTPErrorResponse(resp.StatusCode, resp.Body) + err := parseHTTPErrorResponse(resp) if uErr, ok := err.(*UnexpectedHTTPResponseError); ok && resp.StatusCode == 401 { return errcode.ErrorCodeUnauthorized.WithDetail(uErr.Response) } diff --git a/vendor/github.com/docker/distribution/registry/client/repository.go b/vendor/github.com/docker/distribution/registry/client/repository.go index 04e5a3ba0..fd42a1e66 100644 --- a/vendor/github.com/docker/distribution/registry/client/repository.go +++ b/vendor/github.com/docker/distribution/registry/client/repository.go @@ -14,8 +14,8 @@ import ( "strings" "time" + "github.com/distribution/reference" "github.com/docker/distribution" - "github.com/docker/distribution/reference" v2 "github.com/docker/distribution/registry/api/v2" "github.com/docker/distribution/registry/client/transport" "github.com/docker/distribution/registry/storage/cache" diff --git a/vendor/github.com/docker/distribution/registry/storage/cache/memory/memory.go b/vendor/github.com/docker/distribution/registry/storage/cache/memory/memory.go index 42d94d9bd..f2953b02c 100644 --- a/vendor/github.com/docker/distribution/registry/storage/cache/memory/memory.go +++ b/vendor/github.com/docker/distribution/registry/storage/cache/memory/memory.go @@ -4,8 +4,8 @@ import ( "context" "sync" + "github.com/distribution/reference" "github.com/docker/distribution" - "github.com/docker/distribution/reference" "github.com/docker/distribution/registry/storage/cache" "github.com/opencontainers/go-digest" ) diff --git a/vendor/github.com/docker/distribution/vendor.conf b/vendor/github.com/docker/distribution/vendor.conf index bd1b4bff6..20818428f 100644 --- a/vendor/github.com/docker/distribution/vendor.conf +++ b/vendor/github.com/docker/distribution/vendor.conf @@ -9,6 +9,7 @@ github.com/bugsnag/osext 0dd3f918b21bec95ace9dc86c7e70266cfc5c702 github.com/bugsnag/panicwrap e2c28503fcd0675329da73bf48b33404db873782 github.com/denverdino/aliyungo afedced274aa9a7fcdd47ac97018f0f8db4e5de2 github.com/dgrijalva/jwt-go 4bbdd8ac624fc7a9ef7aec841c43d99b5fe65a29 https://github.com/golang-jwt/jwt.git # v3.2.2 +github.com/distribution/reference 49c28499d219290c3226822e9cfcd4ede6d75379 # v0.5.0 github.com/docker/go-metrics 399ea8c73916000c64c2c76e8da00ca82f8387ab github.com/docker/libtrust fa567046d9b14f6aa788882a950d69651d230b21 github.com/garyburd/redigo 535138d7bcd717d6531c701ef5933d98b1866257 @@ -47,5 +48,5 @@ gopkg.in/check.v1 64131543e7896d5bcc6bd5a76287eb75ea96c673 gopkg.in/square/go-jose.v1 40d457b439244b546f023d056628e5184136899b gopkg.in/yaml.v2 v2.2.1 rsc.io/letsencrypt e770c10b0f1a64775ae91d240407ce00d1a5bdeb https://github.com/dmcgowan/letsencrypt.git -github.com/opencontainers/go-digest a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb +github.com/opencontainers/go-digest ea51bea511f75cfa3ef6098cc253c5c3609b037a # v1.0.0 github.com/opencontainers/image-spec 67d2d5658fe0476ab9bf414cec164077ebff3920 # v1.0.2 diff --git a/vendor/github.com/docker/docker-credential-helpers/client/client.go b/vendor/github.com/docker/docker-credential-helpers/client/client.go index d1d0434cb..678153cf8 100644 --- a/vendor/github.com/docker/docker-credential-helpers/client/client.go +++ b/vendor/github.com/docker/docker-credential-helpers/client/client.go @@ -26,7 +26,7 @@ func isValidCredsMessage(msg string) error { // Store uses an external program to save credentials. func Store(program ProgramFunc, creds *credentials.Credentials) error { - cmd := program("store") + cmd := program(credentials.ActionStore) buffer := new(bytes.Buffer) if err := json.NewEncoder(buffer).Encode(creds); err != nil { @@ -50,7 +50,7 @@ func Store(program ProgramFunc, creds *credentials.Credentials) error { // Get executes an external program to get the credentials from a native store. func Get(program ProgramFunc, serverURL string) (*credentials.Credentials, error) { - cmd := program("get") + cmd := program(credentials.ActionGet) cmd.Input(strings.NewReader(serverURL)) out, err := cmd.Output() @@ -81,7 +81,7 @@ func Get(program ProgramFunc, serverURL string) (*credentials.Credentials, error // Erase executes a program to remove the server credentials from the native store. func Erase(program ProgramFunc, serverURL string) error { - cmd := program("erase") + cmd := program(credentials.ActionErase) cmd.Input(strings.NewReader(serverURL)) out, err := cmd.Output() if err != nil { @@ -99,7 +99,7 @@ func Erase(program ProgramFunc, serverURL string) error { // List executes a program to list server credentials in the native store. func List(program ProgramFunc) (map[string]string, error) { - cmd := program("list") + cmd := program(credentials.ActionList) cmd.Input(strings.NewReader("unused")) out, err := cmd.Output() if err != nil { diff --git a/vendor/github.com/docker/docker-credential-helpers/client/command.go b/vendor/github.com/docker/docker-credential-helpers/client/command.go index 0183c0639..1936234be 100644 --- a/vendor/github.com/docker/docker-credential-helpers/client/command.go +++ b/vendor/github.com/docker/docker-credential-helpers/client/command.go @@ -1,11 +1,9 @@ package client import ( - "fmt" "io" "os" - - exec "golang.org/x/sys/execabs" + "os/exec" ) // Program is an interface to execute external programs. @@ -31,27 +29,26 @@ func NewShellProgramFuncWithEnv(name string, env *map[string]string) ProgramFunc func createProgramCmdRedirectErr(commandName string, args []string, env *map[string]string) *exec.Cmd { programCmd := exec.Command(commandName, args...) - programCmd.Env = os.Environ() if env != nil { for k, v := range *env { - programCmd.Env = append(programCmd.Env, fmt.Sprintf("%s=%s", k, v)) + programCmd.Env = append(programCmd.Environ(), k+"="+v) } } programCmd.Stderr = os.Stderr return programCmd } -// Shell invokes shell commands to talk with a remote credentials helper. +// Shell invokes shell commands to talk with a remote credentials-helper. type Shell struct { cmd *exec.Cmd } -// Output returns responses from the remote credentials helper. +// Output returns responses from the remote credentials-helper. func (s *Shell) Output() ([]byte, error) { return s.cmd.Output() } -// Input sets the input to send to a remote credentials helper. +// Input sets the input to send to a remote credentials-helper. func (s *Shell) Input(in io.Reader) { s.cmd.Stdin = in } diff --git a/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go b/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go index 91d9d4bba..eac551884 100644 --- a/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go +++ b/vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go @@ -10,6 +10,20 @@ import ( "strings" ) +// Action defines the name of an action (sub-command) supported by a +// credential-helper binary. It is an alias for "string", and mostly +// for convenience. +type Action = string + +// List of actions (sub-commands) supported by credential-helper binaries. +const ( + ActionStore Action = "store" + ActionGet Action = "get" + ActionErase Action = "erase" + ActionList Action = "list" + ActionVersion Action = "version" +) + // Credentials holds the information shared between docker and the credentials store. type Credentials struct { ServerURL string @@ -43,42 +57,52 @@ func SetCredsLabel(label string) { CredsLabel = label } -// Serve initializes the credentials helper and parses the action argument. +// Serve initializes the credentials-helper and parses the action argument. // This function is designed to be called from a command line interface. // It uses os.Args[1] as the key for the action. // It uses os.Stdin as input and os.Stdout as output. // This function terminates the program with os.Exit(1) if there is an error. func Serve(helper Helper) { - var err error if len(os.Args) != 2 { - err = fmt.Errorf("Usage: %s ", os.Args[0]) + _, _ = fmt.Fprintln(os.Stdout, usage()) + os.Exit(1) } - if err == nil { - err = HandleCommand(helper, os.Args[1], os.Stdin, os.Stdout) + switch os.Args[1] { + case "--version", "-v": + _ = PrintVersion(os.Stdout) + os.Exit(0) + case "--help", "-h": + _, _ = fmt.Fprintln(os.Stdout, usage()) + os.Exit(0) } - if err != nil { - fmt.Fprintf(os.Stdout, "%v\n", err) + if err := HandleCommand(helper, os.Args[1], os.Stdin, os.Stdout); err != nil { + _, _ = fmt.Fprintln(os.Stdout, err) os.Exit(1) } } -// HandleCommand uses a helper and a key to run a credential action. -func HandleCommand(helper Helper, key string, in io.Reader, out io.Writer) error { - switch key { - case "store": +func usage() string { + return fmt.Sprintf("Usage: %s ", Name) +} + +// HandleCommand runs a helper to execute a credential action. +func HandleCommand(helper Helper, action Action, in io.Reader, out io.Writer) error { + switch action { + case ActionStore: return Store(helper, in) - case "get": + case ActionGet: return Get(helper, in, out) - case "erase": + case ActionErase: return Erase(helper, in) - case "list": + case ActionList: return List(helper, out) - case "version": + case ActionVersion: return PrintVersion(out) + default: + return fmt.Errorf("%s: unknown action: %s", Name, action) } - return fmt.Errorf("Unknown credential action `%s`", key) } // Store uses a helper and an input reader to save credentials. @@ -132,18 +156,17 @@ func Get(helper Helper, reader io.Reader, writer io.Writer) error { return err } - resp := Credentials{ + buffer.Reset() + err = json.NewEncoder(buffer).Encode(Credentials{ ServerURL: serverURL, Username: username, Secret: secret, - } - - buffer.Reset() - if err := json.NewEncoder(buffer).Encode(resp); err != nil { + }) + if err != nil { return err } - fmt.Fprint(writer, buffer.String()) + _, _ = fmt.Fprint(writer, buffer.String()) return nil } @@ -181,6 +204,6 @@ func List(helper Helper, writer io.Writer) error { // PrintVersion outputs the current version. func PrintVersion(writer io.Writer) error { - fmt.Fprintf(writer, "%s (%s) %s\n", Name, Package, Version) + _, _ = fmt.Fprintf(writer, "%s (%s) %s\n", Name, Package, Version) return nil } diff --git a/vendor/github.com/docker/docker-credential-helpers/credentials/error.go b/vendor/github.com/docker/docker-credential-helpers/credentials/error.go index fe6a5aef4..8fa4d5d25 100644 --- a/vendor/github.com/docker/docker-credential-helpers/credentials/error.go +++ b/vendor/github.com/docker/docker-credential-helpers/credentials/error.go @@ -1,5 +1,7 @@ package credentials +import "errors" + const ( // ErrCredentialsNotFound standardizes the not found error, so every helper returns // the same message and docker can handle it properly. @@ -21,6 +23,11 @@ func (errCredentialsNotFound) Error() string { return errCredentialsNotFoundMessage } +// NotFound implements the [ErrNotFound][errdefs.ErrNotFound] interface. +// +// [errdefs.ErrNotFound]: https://pkg.go.dev/github.com/docker/docker@v24.0.1+incompatible/errdefs#ErrNotFound +func (errCredentialsNotFound) NotFound() {} + // NewErrCredentialsNotFound creates a new error // for when the credentials are not in the store. func NewErrCredentialsNotFound() error { @@ -30,8 +37,8 @@ func NewErrCredentialsNotFound() error { // IsErrCredentialsNotFound returns true if the error // was caused by not having a set of credentials in a store. func IsErrCredentialsNotFound(err error) bool { - _, ok := err.(errCredentialsNotFound) - return ok + var target errCredentialsNotFound + return errors.As(err, &target) } // IsErrCredentialsNotFoundMessage returns true if the error @@ -53,6 +60,12 @@ func (errCredentialsMissingServerURL) Error() string { return errCredentialsMissingServerURLMessage } +// InvalidParameter implements the [ErrInvalidParameter][errdefs.ErrInvalidParameter] +// interface. +// +// [errdefs.ErrInvalidParameter]: https://pkg.go.dev/github.com/docker/docker@v24.0.1+incompatible/errdefs#ErrInvalidParameter +func (errCredentialsMissingServerURL) InvalidParameter() {} + // errCredentialsMissingUsername represents an error raised // when the credentials object has no username or when no // username is provided to a credentials operation requiring @@ -63,6 +76,12 @@ func (errCredentialsMissingUsername) Error() string { return errCredentialsMissingUsernameMessage } +// InvalidParameter implements the [ErrInvalidParameter][errdefs.ErrInvalidParameter] +// interface. +// +// [errdefs.ErrInvalidParameter]: https://pkg.go.dev/github.com/docker/docker@v24.0.1+incompatible/errdefs#ErrInvalidParameter +func (errCredentialsMissingUsername) InvalidParameter() {} + // NewErrCredentialsMissingServerURL creates a new error for // errCredentialsMissingServerURL. func NewErrCredentialsMissingServerURL() error { @@ -78,8 +97,8 @@ func NewErrCredentialsMissingUsername() error { // IsCredentialsMissingServerURL returns true if the error // was an errCredentialsMissingServerURL. func IsCredentialsMissingServerURL(err error) bool { - _, ok := err.(errCredentialsMissingServerURL) - return ok + var target errCredentialsMissingServerURL + return errors.As(err, &target) } // IsCredentialsMissingServerURLMessage checks for an @@ -91,8 +110,8 @@ func IsCredentialsMissingServerURLMessage(err string) bool { // IsCredentialsMissingUsername returns true if the error // was an errCredentialsMissingUsername. func IsCredentialsMissingUsername(err error) bool { - _, ok := err.(errCredentialsMissingUsername) - return ok + var target errCredentialsMissingUsername + return errors.As(err, &target) } // IsCredentialsMissingUsernameMessage checks for an diff --git a/vendor/github.com/docker/docker/AUTHORS b/vendor/github.com/docker/docker/AUTHORS index 0728bfe18..b31418192 100644 --- a/vendor/github.com/docker/docker/AUTHORS +++ b/vendor/github.com/docker/docker/AUTHORS @@ -29,6 +29,7 @@ Adam Pointer Adam Singer Adam Walz Adam Williams +AdamKorcz Addam Hardy Aditi Rajagopal Aditya @@ -81,6 +82,7 @@ Alex Goodman Alex Nordlund Alex Olshansky Alex Samorukov +Alex Stockinger Alex Warhawk Alexander Artemenko Alexander Boyd @@ -198,6 +200,7 @@ Anusha Ragunathan Anyu Wang apocas Arash Deshmeh +arcosx ArikaChen Arko Dasgupta Arnaud Lefebvre @@ -241,6 +244,7 @@ Benjamin Atkin Benjamin Baker Benjamin Boudreau Benjamin Böhmke +Benjamin Wang Benjamin Yolken Benny Ng Benoit Chesneau @@ -634,6 +638,7 @@ Eng Zer Jun Enguerran Eohyung Lee epeterso +er0k Eric Barch Eric Curtin Eric G. Noriega @@ -754,6 +759,7 @@ Félix Baylac-Jacqué Félix Cantournet Gabe Rosenhouse Gabor Nagy +Gabriel Adrian Samfira Gabriel Goller Gabriel L. Somlo Gabriel Linder @@ -855,6 +861,7 @@ Hongbin Lu Hongxu Jia Honza Pokorny Hsing-Hui Hsu +Hsing-Yu (David) Chen hsinko <21551195@zju.edu.cn> Hu Keping Hu Tao @@ -887,6 +894,7 @@ Igor Dolzhikov Igor Karpovich Iliana Weller Ilkka Laukkanen +Illia Antypenko Illo Abdulrahim Ilya Dmitrichenko Ilya Gusev @@ -938,6 +946,7 @@ Jamie Hannaford Jamshid Afshar Jan Breig Jan Chren +Jan Garcia Jan Götte Jan Keromnes Jan Koprowski @@ -1206,6 +1215,7 @@ Kimbro Staken Kir Kolyshkin Kiran Gangadharan Kirill SIbirev +Kirk Easterson knappe Kohei Tsuruta Koichi Shiraishi @@ -1240,10 +1250,12 @@ Lars Kellogg-Stedman Lars R. Damerow Lars-Magnus Skog Laszlo Meszaros +Laura Brehm Laura Frank Laurent Bernaille Laurent Erignoux Laurie Voss +Leandro Motta Barros Leandro Siqueira Lee Calcote Lee Chao <932819864@qq.com> @@ -1563,6 +1575,7 @@ Nick Neisen Nick Parker Nick Payne Nick Russo +Nick Santos Nick Stenning Nick Stinemates Nick Wood @@ -1584,6 +1597,7 @@ NikolaMandic Nikolas Garofil Nikolay Edigaryev Nikolay Milovanov +ningmingxiao Nirmal Mehta Nishant Totla NIWA Hideyuki @@ -1615,6 +1629,7 @@ Omri Shiv Onur Filiz Oriol Francès Oscar Bonilla <6f6231@gmail.com> +oscar.chen <2972789494@qq.com> Oskar Niburski Otto Kekäläinen Ouyang Liduo @@ -1822,6 +1837,7 @@ Rory Hunter Rory McCune Ross Boucher Rovanion Luckey +Roy Reznik Royce Remer Rozhnov Alexandr Rudolph Gottesheim @@ -2271,6 +2287,7 @@ Xiaoyu Zhang xichengliudui <1693291525@qq.com> xiekeyang Ximo Guanter Gonzálbez +xin.li Xinbo Weng Xinfeng Liu Xinzi Zhou @@ -2282,6 +2299,7 @@ Yahya yalpul YAMADA Tsuyoshi Yamasaki Masahide +Yamazaki Masashi Yan Feng Yan Zhu Yang Bai diff --git a/vendor/github.com/docker/docker/api/common.go b/vendor/github.com/docker/docker/api/common.go index bee9b875a..cba66bc46 100644 --- a/vendor/github.com/docker/docker/api/common.go +++ b/vendor/github.com/docker/docker/api/common.go @@ -3,7 +3,7 @@ package api // import "github.com/docker/docker/api" // Common constants for daemon and client. const ( // DefaultVersion of Current REST API - DefaultVersion = "1.42" + DefaultVersion = "1.43" // NoBaseImageSpecifier is the symbol used by the FROM // command to specify that no base image is to be used. diff --git a/vendor/github.com/docker/docker/api/swagger.yaml b/vendor/github.com/docker/docker/api/swagger.yaml index afe7a8c37..7635b9f66 100644 --- a/vendor/github.com/docker/docker/api/swagger.yaml +++ b/vendor/github.com/docker/docker/api/swagger.yaml @@ -19,10 +19,10 @@ produces: consumes: - "application/json" - "text/plain" -basePath: "/v1.42" +basePath: "/v1.43" info: title: "Docker Engine API" - version: "1.42" + version: "1.43" x-logo: url: "https://docs.docker.com/assets/images/logo-docker-main.png" description: | @@ -55,8 +55,8 @@ info: the URL is not supported by the daemon, a HTTP `400 Bad Request` error message is returned. - If you omit the version-prefix, the current version of the API (v1.42) is used. - For example, calling `/info` is the same as calling `/v1.42/info`. Using the + If you omit the version-prefix, the current version of the API (v1.43) is used. + For example, calling `/info` is the same as calling `/v1.43/info`. Using the API without a version-prefix is deprecated and will be removed in a future release. Engine releases in the near future should support this version of the API, @@ -976,6 +976,13 @@ definitions: items: type: "integer" minimum: 0 + Annotations: + type: "object" + description: | + Arbitrary non-identifying metadata attached to container and + provided to the runtime when the container is started. + additionalProperties: + type: "string" # Applicable to UNIX platforms CapAdd: @@ -1122,6 +1129,7 @@ definitions: remapping option is enabled. ShmSize: type: "integer" + format: "int64" description: | Size of `/dev/shm` in bytes. If omitted, the system uses 64MB. minimum: 0 @@ -1610,6 +1618,34 @@ definitions: "WorkDir": "/var/lib/docker/overlay2/ef749362d13333e65fc95c572eb525abbe0052e16e086cb64bc3b98ae9aa6d74/work" } + FilesystemChange: + description: | + Change in the container's filesystem. + type: "object" + required: [Path, Kind] + properties: + Path: + description: | + Path to file or directory that has changed. + type: "string" + x-nullable: false + Kind: + $ref: "#/definitions/ChangeType" + + ChangeType: + description: | + Kind of change + + Can be one of: + + - `0`: Modified ("C") + - `1`: Added ("A") + - `2`: Deleted ("D") + type: "integer" + format: "uint8" + enum: [0, 1, 2] + x-nullable: false + ImageInspect: description: | Information about an image in the local image cache. @@ -1746,15 +1782,14 @@ definitions: Total size of the image including all layers it is composed of. In versions of Docker before v1.10, this field was calculated from - the image itself and all of its parent images. Docker v1.10 and up - store images self-contained, and no longer use a parent-chain, making - this field an equivalent of the Size field. + the image itself and all of its parent images. Images are now stored + self-contained, and no longer use a parent-chain, making this field + an equivalent of the Size field. - This field is kept for backward compatibility, but may be removed in - a future version of the API. + > **Deprecated**: this field is kept for backward compatibility, but + > will be removed in API v1.44. type: "integer" format: "int64" - x-nullable: false example: 1239828 GraphDriver: $ref: "#/definitions/GraphDriverData" @@ -1802,7 +1837,6 @@ definitions: - Created - Size - SharedSize - - VirtualSize - Labels - Containers properties: @@ -1888,19 +1922,17 @@ definitions: x-nullable: false example: 1239828 VirtualSize: - description: | + description: |- Total size of the image including all layers it is composed of. In versions of Docker before v1.10, this field was calculated from - the image itself and all of its parent images. Docker v1.10 and up - store images self-contained, and no longer use a parent-chain, making - this field an equivalent of the Size field. + the image itself and all of its parent images. Images are now stored + self-contained, and no longer use a parent-chain, making this field + an equivalent of the Size field. - This field is kept for backward compatibility, but may be removed in - a future version of the API. + Deprecated: this field is kept for backward compatibility, and will be removed in API v1.44. type: "integer" format: "int64" - x-nullable: false example: 172064416 Labels: description: "User-defined key/value metadata." @@ -4652,7 +4684,8 @@ definitions: example: false OOMKilled: description: | - Whether this container has been killed because it ran out of memory. + Whether a process within this container has been killed because it ran + out of memory since the container was last started. type: "boolean" example: false Dead: @@ -5035,7 +5068,7 @@ definitions: Go runtime (`GOOS`). Currently returned values are "linux" and "windows". A full list of - possible values can be found in the [Go documentation](https://golang.org/doc/install/source#environment). + possible values can be found in the [Go documentation](https://go.dev/doc/install/source#environment). type: "string" example: "linux" Architecture: @@ -5043,7 +5076,7 @@ definitions: Hardware architecture of the host, as returned by the Go runtime (`GOARCH`). - A full list of possible values can be found in the [Go documentation](https://golang.org/doc/install/source#environment). + A full list of possible values can be found in the [Go documentation](https://go.dev/doc/install/source#environment). type: "string" example: "x86_64" NCPU: @@ -5129,42 +5162,8 @@ definitions: ServerVersion: description: | Version string of the daemon. - - > **Note**: the [standalone Swarm API](https://docs.docker.com/swarm/swarm-api/) - > returns the Swarm version instead of the daemon version, for example - > `swarm/1.2.8`. type: "string" - example: "17.06.0-ce" - ClusterStore: - description: | - URL of the distributed storage backend. - - - The storage backend is used for multihost networking (to store - network and endpoint information) and by the node discovery mechanism. - -


- - > **Deprecated**: This field is only propagated when using standalone Swarm - > mode, and overlay networking using an external k/v store. Overlay - > networks with Swarm mode enabled use the built-in raft store, and - > this field will be empty. - type: "string" - example: "consul://consul.corp.example.com:8600/some/path" - ClusterAdvertise: - description: | - The network endpoint that the Engine advertises for the purpose of - node discovery. ClusterAdvertise is a `host:port` combination on which - the daemon is reachable by other hosts. - -


- - > **Deprecated**: This field is only propagated when using standalone Swarm - > mode, and overlay networking using an external k/v store. Overlay - > networks with Swarm mode enabled use the built-in raft store, and - > this field will be empty. - type: "string" - example: "node5.corp.example.com:8000" + example: "24.0.2" Runtimes: description: | List of [OCI compliant](https://github.com/opencontainers/runtime-spec) @@ -5242,7 +5241,8 @@ definitions: SecurityOptions: description: | List of security features that are enabled on the daemon, such as - apparmor, seccomp, SELinux, user-namespaces (userns), and rootless. + apparmor, seccomp, SELinux, user-namespaces (userns), rootless and + no-new-privileges. Additional configuration options for each security feature may be present, and are included as a comma-separated list of key/value @@ -6875,9 +6875,9 @@ paths: Returns which files in a container's filesystem have been added, deleted, or modified. The `Kind` of modification can be one of: - - `0`: Modified - - `1`: Added - - `2`: Deleted + - `0`: Modified ("C") + - `1`: Added ("A") + - `2`: Deleted ("D") operationId: "ContainerChanges" produces: ["application/json"] responses: @@ -6886,22 +6886,7 @@ paths: schema: type: "array" items: - type: "object" - x-go-name: "ContainerChangeResponseItem" - title: "ContainerChangeResponseItem" - description: "change item in response to ContainerChanges operation" - required: [Path, Kind] - properties: - Path: - description: "Path to file that has changed" - type: "string" - x-nullable: false - Kind: - description: "Kind of change" - type: "integer" - format: "uint8" - enum: [0, 1, 2] - x-nullable: false + $ref: "#/definitions/FilesystemChange" examples: application/json: - Path: "/dev" @@ -8228,7 +8213,7 @@ paths: Available filters: - - `until=`: duration relative to daemon's time, during which build cache was not used, in Go's duration format (e.g., '24h') + - `until=` remove cache older than ``. The `` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon's local time. - `id=` - `parent=` - `type=` @@ -9911,7 +9896,9 @@ paths: Id: "22be93d5babb089c5aab8dbc369042fad48ff791584ca2da2100db837a1c7c30" Warning: "" 403: - description: "operation not supported for pre-defined networks" + description: | + Forbidden operation. This happens when trying to create a network named after a pre-defined network, + or when trying to create an overlay network on a daemon which is not part of a Swarm cluster. schema: $ref: "#/definitions/ErrorResponse" 404: @@ -10374,6 +10361,12 @@ paths: default if omitted. required: true type: "string" + - name: "force" + in: "query" + description: | + Force disable a plugin even if still in use. + required: false + type: "boolean" tags: ["Plugin"] /plugins/{name}/upgrade: post: diff --git a/vendor/github.com/docker/docker/api/types/auth.go b/vendor/github.com/docker/docker/api/types/auth.go index ddf15bb18..9ee329a2f 100644 --- a/vendor/github.com/docker/docker/api/types/auth.go +++ b/vendor/github.com/docker/docker/api/types/auth.go @@ -1,22 +1,7 @@ package types // import "github.com/docker/docker/api/types" +import "github.com/docker/docker/api/types/registry" -// AuthConfig contains authorization information for connecting to a Registry -type AuthConfig struct { - Username string `json:"username,omitempty"` - Password string `json:"password,omitempty"` - Auth string `json:"auth,omitempty"` - - // Email is an optional value associated with the username. - // This field is deprecated and will be removed in a later - // version of docker. - Email string `json:"email,omitempty"` - - ServerAddress string `json:"serveraddress,omitempty"` - - // IdentityToken is used to authenticate the user and get - // an access token for the registry. - IdentityToken string `json:"identitytoken,omitempty"` - - // RegistryToken is a bearer token to be sent to a registry - RegistryToken string `json:"registrytoken,omitempty"` -} +// AuthConfig contains authorization information for connecting to a Registry. +// +// Deprecated: use github.com/docker/docker/api/types/registry.AuthConfig +type AuthConfig = registry.AuthConfig diff --git a/vendor/github.com/docker/docker/api/types/client.go b/vendor/github.com/docker/docker/api/types/client.go index 97aca0230..d8cd30613 100644 --- a/vendor/github.com/docker/docker/api/types/client.go +++ b/vendor/github.com/docker/docker/api/types/client.go @@ -7,6 +7,7 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/registry" units "github.com/docker/go-units" ) @@ -180,7 +181,7 @@ type ImageBuildOptions struct { // at all (nil). See the parsing of buildArgs in // api/server/router/build/build_routes.go for even more info. BuildArgs map[string]*string - AuthConfigs map[string]AuthConfig + AuthConfigs map[string]registry.AuthConfig Context io.Reader Labels map[string]string // squash the resulting image's layers to the parent diff --git a/vendor/github.com/docker/docker/api/types/configs.go b/vendor/github.com/docker/docker/api/types/configs.go index 7689f38b3..7d5930bbe 100644 --- a/vendor/github.com/docker/docker/api/types/configs.go +++ b/vendor/github.com/docker/docker/api/types/configs.go @@ -3,7 +3,7 @@ package types // import "github.com/docker/docker/api/types" import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" - specs "github.com/opencontainers/image-spec/specs-go/v1" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) // configs holds structs used for internal communication between the @@ -16,7 +16,7 @@ type ContainerCreateConfig struct { Config *container.Config HostConfig *container.HostConfig NetworkingConfig *network.NetworkingConfig - Platform *specs.Platform + Platform *ocispec.Platform AdjustCPUShares bool } diff --git a/vendor/github.com/docker/docker/api/types/container/change_response_deprecated.go b/vendor/github.com/docker/docker/api/types/container/change_response_deprecated.go new file mode 100644 index 000000000..6b4b47390 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/change_response_deprecated.go @@ -0,0 +1,6 @@ +package container + +// ContainerChangeResponseItem change item in response to ContainerChanges operation +// +// Deprecated: use [FilesystemChange]. +type ContainerChangeResponseItem = FilesystemChange diff --git a/vendor/github.com/docker/docker/api/types/container/change_type.go b/vendor/github.com/docker/docker/api/types/container/change_type.go new file mode 100644 index 000000000..fe8d6d369 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/change_type.go @@ -0,0 +1,15 @@ +package container + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +// ChangeType Kind of change +// +// Can be one of: +// +// - `0`: Modified ("C") +// - `1`: Added ("A") +// - `2`: Deleted ("D") +// +// swagger:model ChangeType +type ChangeType uint8 diff --git a/vendor/github.com/docker/docker/api/types/container/change_types.go b/vendor/github.com/docker/docker/api/types/container/change_types.go new file mode 100644 index 000000000..3a3a83866 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/change_types.go @@ -0,0 +1,23 @@ +package container + +const ( + // ChangeModify represents the modify operation. + ChangeModify ChangeType = 0 + // ChangeAdd represents the add operation. + ChangeAdd ChangeType = 1 + // ChangeDelete represents the delete operation. + ChangeDelete ChangeType = 2 +) + +func (ct ChangeType) String() string { + switch ct { + case ChangeModify: + return "C" + case ChangeAdd: + return "A" + case ChangeDelete: + return "D" + default: + return "" + } +} diff --git a/vendor/github.com/docker/docker/api/types/container/container_changes.go b/vendor/github.com/docker/docker/api/types/container/container_changes.go deleted file mode 100644 index 16dd5019e..000000000 --- a/vendor/github.com/docker/docker/api/types/container/container_changes.go +++ /dev/null @@ -1,20 +0,0 @@ -package container // import "github.com/docker/docker/api/types/container" - -// ---------------------------------------------------------------------------- -// Code generated by `swagger generate operation`. DO NOT EDIT. -// -// See hack/generate-swagger-api.sh -// ---------------------------------------------------------------------------- - -// ContainerChangeResponseItem change item in response to ContainerChanges operation -// swagger:model ContainerChangeResponseItem -type ContainerChangeResponseItem struct { - - // Kind of change - // Required: true - Kind uint8 `json:"Kind"` - - // Path to file that has changed - // Required: true - Path string `json:"Path"` -} diff --git a/vendor/github.com/docker/docker/api/types/container/deprecated.go b/vendor/github.com/docker/docker/api/types/container/deprecated.go deleted file mode 100644 index 0cb70e363..000000000 --- a/vendor/github.com/docker/docker/api/types/container/deprecated.go +++ /dev/null @@ -1,16 +0,0 @@ -package container // import "github.com/docker/docker/api/types/container" - -// ContainerCreateCreatedBody OK response to ContainerCreate operation -// -// Deprecated: use CreateResponse -type ContainerCreateCreatedBody = CreateResponse - -// ContainerWaitOKBody OK response to ContainerWait operation -// -// Deprecated: use WaitResponse -type ContainerWaitOKBody = WaitResponse - -// ContainerWaitOKBodyError container waiting error, if any -// -// Deprecated: use WaitExitError -type ContainerWaitOKBodyError = WaitExitError diff --git a/vendor/github.com/docker/docker/api/types/container/filesystem_change.go b/vendor/github.com/docker/docker/api/types/container/filesystem_change.go new file mode 100644 index 000000000..9e9c2ad1d --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/container/filesystem_change.go @@ -0,0 +1,19 @@ +package container + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +// FilesystemChange Change in the container's filesystem. +// +// swagger:model FilesystemChange +type FilesystemChange struct { + + // kind + // Required: true + Kind ChangeType `json:"Kind"` + + // Path to file or directory that has changed. + // + // Required: true + Path string `json:"Path"` +} diff --git a/vendor/github.com/docker/docker/api/types/container/host_config.go b/vendor/github.com/docker/docker/api/types/container/hostconfig.go similarity index 84% rename from vendor/github.com/docker/docker/api/types/container/host_config.go rename to vendor/github.com/docker/docker/api/types/container/hostconfig.go index 100f434ce..d4e6f5537 100644 --- a/vendor/github.com/docker/docker/api/types/container/host_config.go +++ b/vendor/github.com/docker/docker/api/types/container/hostconfig.go @@ -101,7 +101,8 @@ func (n IpcMode) IsShareable() bool { // IsContainer indicates whether the container uses another container's ipc namespace. func (n IpcMode) IsContainer() bool { - return strings.HasPrefix(string(n), string(IPCModeContainer)+":") + _, ok := containerID(string(n)) + return ok } // IsNone indicates whether container IpcMode is set to "none". @@ -116,15 +117,14 @@ func (n IpcMode) IsEmpty() bool { // Valid indicates whether the ipc mode is valid. func (n IpcMode) Valid() bool { + // TODO(thaJeztah): align with PidMode, and consider container-mode without a container name/ID to be invalid. return n.IsEmpty() || n.IsNone() || n.IsPrivate() || n.IsHost() || n.IsShareable() || n.IsContainer() } // Container returns the name of the container ipc stack is going to be used. -func (n IpcMode) Container() string { - if n.IsContainer() { - return strings.TrimPrefix(string(n), string(IPCModeContainer)+":") - } - return "" +func (n IpcMode) Container() (idOrName string) { + idOrName, _ = containerID(string(n)) + return idOrName } // NetworkMode represents the container network stack. @@ -147,17 +147,14 @@ func (n NetworkMode) IsPrivate() bool { // IsContainer indicates whether container uses a container network stack. func (n NetworkMode) IsContainer() bool { - parts := strings.SplitN(string(n), ":", 2) - return len(parts) > 1 && parts[0] == "container" + _, ok := containerID(string(n)) + return ok } // ConnectedContainer is the id of the container which network this container is connected to. -func (n NetworkMode) ConnectedContainer() string { - parts := strings.SplitN(string(n), ":", 2) - if len(parts) > 1 { - return parts[1] - } - return "" +func (n NetworkMode) ConnectedContainer() (idOrName string) { + idOrName, _ = containerID(string(n)) + return idOrName } // UserDefined indicates user-created network @@ -178,18 +175,12 @@ func (n UsernsMode) IsHost() bool { // IsPrivate indicates whether the container uses the a private userns. func (n UsernsMode) IsPrivate() bool { - return !(n.IsHost()) + return !n.IsHost() } // Valid indicates whether the userns is valid. func (n UsernsMode) Valid() bool { - parts := strings.Split(string(n), ":") - switch mode := parts[0]; mode { - case "", "host": - default: - return false - } - return true + return n == "" || n.IsHost() } // CgroupSpec represents the cgroup to use for the container. @@ -197,22 +188,20 @@ type CgroupSpec string // IsContainer indicates whether the container is using another container cgroup func (c CgroupSpec) IsContainer() bool { - parts := strings.SplitN(string(c), ":", 2) - return len(parts) > 1 && parts[0] == "container" + _, ok := containerID(string(c)) + return ok } // Valid indicates whether the cgroup spec is valid. func (c CgroupSpec) Valid() bool { - return c.IsContainer() || c == "" + // TODO(thaJeztah): align with PidMode, and consider container-mode without a container name/ID to be invalid. + return c == "" || c.IsContainer() } -// Container returns the name of the container whose cgroup will be used. -func (c CgroupSpec) Container() string { - parts := strings.SplitN(string(c), ":", 2) - if len(parts) > 1 { - return parts[1] - } - return "" +// Container returns the ID or name of the container whose cgroup will be used. +func (c CgroupSpec) Container() (idOrName string) { + idOrName, _ = containerID(string(c)) + return idOrName } // UTSMode represents the UTS namespace of the container. @@ -220,7 +209,7 @@ type UTSMode string // IsPrivate indicates whether the container uses its private UTS namespace. func (n UTSMode) IsPrivate() bool { - return !(n.IsHost()) + return !n.IsHost() } // IsHost indicates whether the container uses the host's UTS namespace. @@ -230,13 +219,7 @@ func (n UTSMode) IsHost() bool { // Valid indicates whether the UTS namespace is valid. func (n UTSMode) Valid() bool { - parts := strings.Split(string(n), ":") - switch mode := parts[0]; mode { - case "", "host": - default: - return false - } - return true + return n == "" || n.IsHost() } // PidMode represents the pid namespace of the container. @@ -254,32 +237,19 @@ func (n PidMode) IsHost() bool { // IsContainer indicates whether the container uses a container's pid namespace. func (n PidMode) IsContainer() bool { - parts := strings.SplitN(string(n), ":", 2) - return len(parts) > 1 && parts[0] == "container" + _, ok := containerID(string(n)) + return ok } // Valid indicates whether the pid namespace is valid. func (n PidMode) Valid() bool { - parts := strings.Split(string(n), ":") - switch mode := parts[0]; mode { - case "", "host": - case "container": - if len(parts) != 2 || parts[1] == "" { - return false - } - default: - return false - } - return true + return n == "" || n.IsHost() || validContainer(string(n)) } // Container returns the name of the container whose pid namespace is going to be used. -func (n PidMode) Container() string { - parts := strings.SplitN(string(n), ":", 2) - if len(parts) > 1 { - return parts[1] - } - return "" +func (n PidMode) Container() (idOrName string) { + idOrName, _ = containerID(string(n)) + return idOrName } // DeviceRequest represents a request for devices from a device driver. @@ -408,16 +378,17 @@ type UpdateConfig struct { // Portable information *should* appear in Config. type HostConfig struct { // Applicable to all platforms - Binds []string // List of volume bindings for this container - ContainerIDFile string // File (path) where the containerId is written - LogConfig LogConfig // Configuration of the logs for this container - NetworkMode NetworkMode // Network mode to use for the container - PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host - RestartPolicy RestartPolicy // Restart policy to be used for the container - AutoRemove bool // Automatically remove container when it exits - VolumeDriver string // Name of the volume driver used to mount volumes - VolumesFrom []string // List of volumes to take from other container - ConsoleSize [2]uint // Initial console size (height,width) + Binds []string // List of volume bindings for this container + ContainerIDFile string // File (path) where the containerId is written + LogConfig LogConfig // Configuration of the logs for this container + NetworkMode NetworkMode // Network mode to use for the container + PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host + RestartPolicy RestartPolicy // Restart policy to be used for the container + AutoRemove bool // Automatically remove container when it exits + VolumeDriver string // Name of the volume driver used to mount volumes + VolumesFrom []string // List of volumes to take from other container + ConsoleSize [2]uint // Initial console size (height,width) + Annotations map[string]string `json:",omitempty"` // Arbitrary non-identifying metadata attached to container and provided to the runtime // Applicable to UNIX platforms CapAdd strslice.StrSlice // List of kernel capabilities to add to the container @@ -463,3 +434,23 @@ type HostConfig struct { // Run a custom init inside the container, if null, use the daemon's configured settings Init *bool `json:",omitempty"` } + +// containerID splits "container:" values. It returns the container +// ID or name, and whether an ID/name was found. It returns an empty string and +// a "false" if the value does not have a "container:" prefix. Further validation +// of the returned, including checking if the value is empty, should be handled +// by the caller. +func containerID(val string) (idOrName string, ok bool) { + k, v, hasSep := strings.Cut(val, ":") + if !hasSep || k != "container" { + return "", false + } + return v, true +} + +// validContainer checks if the given value is a "container:" mode with +// a non-empty name/ID. +func validContainer(val string) bool { + id, ok := containerID(val) + return ok && id != "" +} diff --git a/vendor/github.com/docker/docker/api/types/deprecated.go b/vendor/github.com/docker/docker/api/types/deprecated.go deleted file mode 100644 index 216d1df0f..000000000 --- a/vendor/github.com/docker/docker/api/types/deprecated.go +++ /dev/null @@ -1,14 +0,0 @@ -package types // import "github.com/docker/docker/api/types" - -import "github.com/docker/docker/api/types/volume" - -// Volume volume -// -// Deprecated: use github.com/docker/docker/api/types/volume.Volume -type Volume = volume.Volume - -// VolumeUsageData Usage details about the volume. This information is used by the -// `GET /system/df` endpoint, and omitted in other endpoints. -// -// Deprecated: use github.com/docker/docker/api/types/volume.UsageData -type VolumeUsageData = volume.UsageData diff --git a/vendor/github.com/docker/docker/api/types/filters/errors.go b/vendor/github.com/docker/docker/api/types/filters/errors.go new file mode 100644 index 000000000..f52f69440 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/filters/errors.go @@ -0,0 +1,37 @@ +package filters + +import "fmt" + +// invalidFilter indicates that the provided filter or its value is invalid +type invalidFilter struct { + Filter string + Value []string +} + +func (e invalidFilter) Error() string { + msg := "invalid filter" + if e.Filter != "" { + msg += " '" + e.Filter + if e.Value != nil { + msg = fmt.Sprintf("%s=%s", msg, e.Value) + } + msg += "'" + } + return msg +} + +// InvalidParameter marks this error as ErrInvalidParameter +func (e invalidFilter) InvalidParameter() {} + +// unreachableCode is an error indicating that the code path was not expected to be reached. +type unreachableCode struct { + Filter string + Value []string +} + +// System marks this error as ErrSystem +func (e unreachableCode) System() {} + +func (e unreachableCode) Error() string { + return fmt.Sprintf("unreachable code reached for filter: %q with values: %s", e.Filter, e.Value) +} diff --git a/vendor/github.com/docker/docker/api/types/filters/parse.go b/vendor/github.com/docker/docker/api/types/filters/parse.go index f8fe79407..0c39ab5f1 100644 --- a/vendor/github.com/docker/docker/api/types/filters/parse.go +++ b/vendor/github.com/docker/docker/api/types/filters/parse.go @@ -10,7 +10,6 @@ import ( "strings" "github.com/docker/docker/api/types/versions" - "github.com/pkg/errors" ) // Args stores a mapping of keys to a set of multiple values. @@ -99,7 +98,7 @@ func FromJSON(p string) (Args, error) { // Fallback to parsing arguments in the legacy slice format deprecated := map[string][]string{} if legacyErr := json.Unmarshal(raw, &deprecated); legacyErr != nil { - return args, invalidFilter{errors.Wrap(err, "invalid filter")} + return args, &invalidFilter{} } args.fields = deprecatedArgs(deprecated) @@ -163,13 +162,13 @@ func (args Args) MatchKVList(key string, sources map[string]string) bool { } for value := range fieldValues { - testKV := strings.SplitN(value, "=", 2) + testK, testV, hasValue := strings.Cut(value, "=") - v, ok := sources[testKV[0]] + v, ok := sources[testK] if !ok { return false } - if len(testKV) == 2 && testKV[1] != v { + if hasValue && testV != v { return false } } @@ -196,6 +195,38 @@ func (args Args) Match(field, source string) bool { return false } +// GetBoolOrDefault returns a boolean value of the key if the key is present +// and is intepretable as a boolean value. Otherwise the default value is returned. +// Error is not nil only if the filter values are not valid boolean or are conflicting. +func (args Args) GetBoolOrDefault(key string, defaultValue bool) (bool, error) { + fieldValues, ok := args.fields[key] + + if !ok { + return defaultValue, nil + } + + if len(fieldValues) == 0 { + return defaultValue, &invalidFilter{key, nil} + } + + isFalse := fieldValues["0"] || fieldValues["false"] + isTrue := fieldValues["1"] || fieldValues["true"] + + conflicting := isFalse && isTrue + invalid := !isFalse && !isTrue + + if conflicting || invalid { + return defaultValue, &invalidFilter{key, args.Get(key)} + } else if isFalse { + return false, nil + } else if isTrue { + return true, nil + } + + // This code shouldn't be reached. + return defaultValue, &unreachableCode{Filter: key, Value: args.Get(key)} +} + // ExactMatch returns true if the source matches exactly one of the values. func (args Args) ExactMatch(key, source string) bool { fieldValues, ok := args.fields[key] @@ -246,20 +277,12 @@ func (args Args) Contains(field string) bool { return ok } -type invalidFilter struct{ error } - -func (e invalidFilter) Error() string { - return e.error.Error() -} - -func (invalidFilter) InvalidParameter() {} - // Validate compared the set of accepted keys against the keys in the mapping. // An error is returned if any mapping keys are not in the accepted set. func (args Args) Validate(accepted map[string]bool) error { for name := range args.fields { if !accepted[name] { - return invalidFilter{errors.New("invalid filter '" + name + "'")} + return &invalidFilter{name, nil} } } return nil diff --git a/vendor/github.com/docker/docker/api/types/image/opts.go b/vendor/github.com/docker/docker/api/types/image/opts.go new file mode 100644 index 000000000..3cefecb0d --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/image/opts.go @@ -0,0 +1,9 @@ +package image + +import ocispec "github.com/opencontainers/image-spec/specs-go/v1" + +// GetImageOpts holds parameters to inspect an image. +type GetImageOpts struct { + Platform *ocispec.Platform + Details bool +} diff --git a/vendor/github.com/docker/docker/api/types/image_summary.go b/vendor/github.com/docker/docker/api/types/image_summary.go index 90b983a25..0f6f14484 100644 --- a/vendor/github.com/docker/docker/api/types/image_summary.go +++ b/vendor/github.com/docker/docker/api/types/image_summary.go @@ -85,13 +85,10 @@ type ImageSummary struct { // Total size of the image including all layers it is composed of. // // In versions of Docker before v1.10, this field was calculated from - // the image itself and all of its parent images. Docker v1.10 and up - // store images self-contained, and no longer use a parent-chain, making - // this field an equivalent of the Size field. + // the image itself and all of its parent images. Images are now stored + // self-contained, and no longer use a parent-chain, making this field + // an equivalent of the Size field. // - // This field is kept for backward compatibility, but may be removed in - // a future version of the API. - // - // Required: true - VirtualSize int64 `json:"VirtualSize"` + // Deprecated: this field is kept for backward compatibility, and will be removed in API v1.44. + VirtualSize int64 `json:"VirtualSize,omitempty"` } diff --git a/vendor/github.com/docker/docker/api/types/registry/authconfig.go b/vendor/github.com/docker/docker/api/types/registry/authconfig.go new file mode 100644 index 000000000..97a924e37 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/registry/authconfig.go @@ -0,0 +1,99 @@ +package registry // import "github.com/docker/docker/api/types/registry" +import ( + "encoding/base64" + "encoding/json" + "io" + "strings" + + "github.com/pkg/errors" +) + +// AuthHeader is the name of the header used to send encoded registry +// authorization credentials for registry operations (push/pull). +const AuthHeader = "X-Registry-Auth" + +// AuthConfig contains authorization information for connecting to a Registry. +type AuthConfig struct { + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + Auth string `json:"auth,omitempty"` + + // Email is an optional value associated with the username. + // This field is deprecated and will be removed in a later + // version of docker. + Email string `json:"email,omitempty"` + + ServerAddress string `json:"serveraddress,omitempty"` + + // IdentityToken is used to authenticate the user and get + // an access token for the registry. + IdentityToken string `json:"identitytoken,omitempty"` + + // RegistryToken is a bearer token to be sent to a registry + RegistryToken string `json:"registrytoken,omitempty"` +} + +// EncodeAuthConfig serializes the auth configuration as a base64url encoded +// RFC4648, section 5) JSON string for sending through the X-Registry-Auth header. +// +// For details on base64url encoding, see: +// - RFC4648, section 5: https://tools.ietf.org/html/rfc4648#section-5 +func EncodeAuthConfig(authConfig AuthConfig) (string, error) { + buf, err := json.Marshal(authConfig) + if err != nil { + return "", errInvalidParameter{err} + } + return base64.URLEncoding.EncodeToString(buf), nil +} + +// DecodeAuthConfig decodes base64url encoded (RFC4648, section 5) JSON +// authentication information as sent through the X-Registry-Auth header. +// +// This function always returns an AuthConfig, even if an error occurs. It is up +// to the caller to decide if authentication is required, and if the error can +// be ignored. +// +// For details on base64url encoding, see: +// - RFC4648, section 5: https://tools.ietf.org/html/rfc4648#section-5 +func DecodeAuthConfig(authEncoded string) (*AuthConfig, error) { + if authEncoded == "" { + return &AuthConfig{}, nil + } + + authJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded)) + return decodeAuthConfigFromReader(authJSON) +} + +// DecodeAuthConfigBody decodes authentication information as sent as JSON in the +// body of a request. This function is to provide backward compatibility with old +// clients and API versions. Current clients and API versions expect authentication +// to be provided through the X-Registry-Auth header. +// +// Like DecodeAuthConfig, this function always returns an AuthConfig, even if an +// error occurs. It is up to the caller to decide if authentication is required, +// and if the error can be ignored. +func DecodeAuthConfigBody(rdr io.ReadCloser) (*AuthConfig, error) { + return decodeAuthConfigFromReader(rdr) +} + +func decodeAuthConfigFromReader(rdr io.Reader) (*AuthConfig, error) { + authConfig := &AuthConfig{} + if err := json.NewDecoder(rdr).Decode(authConfig); err != nil { + // always return an (empty) AuthConfig to increase compatibility with + // the existing API. + return &AuthConfig{}, invalid(err) + } + return authConfig, nil +} + +func invalid(err error) error { + return errInvalidParameter{errors.Wrap(err, "invalid X-Registry-Auth header")} +} + +type errInvalidParameter struct{ error } + +func (errInvalidParameter) InvalidParameter() {} + +func (e errInvalidParameter) Cause() error { return e.error } + +func (e errInvalidParameter) Unwrap() error { return e.error } diff --git a/vendor/github.com/docker/docker/api/types/registry/registry.go b/vendor/github.com/docker/docker/api/types/registry/registry.go index 62a88f5be..b83f5d7b2 100644 --- a/vendor/github.com/docker/docker/api/types/registry/registry.go +++ b/vendor/github.com/docker/docker/api/types/registry/registry.go @@ -4,7 +4,7 @@ import ( "encoding/json" "net" - v1 "github.com/opencontainers/image-spec/specs-go/v1" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) // ServiceConfig stores daemon registry services configuration. @@ -113,8 +113,8 @@ type SearchResults struct { type DistributionInspect struct { // Descriptor contains information about the manifest, including // the content addressable digest - Descriptor v1.Descriptor + Descriptor ocispec.Descriptor // Platforms contains the list of platforms supported by the image, // obtained by parsing the manifest - Platforms []v1.Platform + Platforms []ocispec.Platform } diff --git a/vendor/github.com/docker/docker/api/types/time/timestamp.go b/vendor/github.com/docker/docker/api/types/time/timestamp.go index 2a74b7a59..cab5c32e3 100644 --- a/vendor/github.com/docker/docker/api/types/time/timestamp.go +++ b/vendor/github.com/docker/docker/api/types/time/timestamp.go @@ -95,37 +95,37 @@ func GetTimestamp(value string, reference time.Time) (string, error) { return fmt.Sprintf("%d.%09d", t.Unix(), int64(t.Nanosecond())), nil } -// ParseTimestamps returns seconds and nanoseconds from a timestamp that has the -// format "%d.%09d", time.Unix(), int64(time.Nanosecond())) -// if the incoming nanosecond portion is longer or shorter than 9 digits it is -// converted to nanoseconds. The expectation is that the seconds and -// seconds will be used to create a time variable. For example: +// ParseTimestamps returns seconds and nanoseconds from a timestamp that has +// the format ("%d.%09d", time.Unix(), int64(time.Nanosecond())). +// If the incoming nanosecond portion is longer than 9 digits it is truncated. +// The expectation is that the seconds and nanoseconds will be used to create a +// time variable. For example: // -// seconds, nanoseconds, err := ParseTimestamp("1136073600.000000001",0) -// if err == nil since := time.Unix(seconds, nanoseconds) +// seconds, nanoseconds, _ := ParseTimestamp("1136073600.000000001",0) +// since := time.Unix(seconds, nanoseconds) // -// returns seconds as def(aultSeconds) if value == "" -func ParseTimestamps(value string, def int64) (int64, int64, error) { +// returns seconds as defaultSeconds if value == "" +func ParseTimestamps(value string, defaultSeconds int64) (seconds int64, nanoseconds int64, err error) { if value == "" { - return def, 0, nil + return defaultSeconds, 0, nil } return parseTimestamp(value) } -func parseTimestamp(value string) (int64, int64, error) { - sa := strings.SplitN(value, ".", 2) - s, err := strconv.ParseInt(sa[0], 10, 64) +func parseTimestamp(value string) (sec int64, nsec int64, err error) { + s, n, ok := strings.Cut(value, ".") + sec, err = strconv.ParseInt(s, 10, 64) if err != nil { - return s, 0, err + return sec, 0, err } - if len(sa) != 2 { - return s, 0, nil + if !ok { + return sec, 0, nil } - n, err := strconv.ParseInt(sa[1], 10, 64) + nsec, err = strconv.ParseInt(n, 10, 64) if err != nil { - return s, n, err + return sec, nsec, err } // should already be in nanoseconds but just in case convert n to nanoseconds - n = int64(float64(n) * math.Pow(float64(10), float64(9-len(sa[1])))) - return s, n, nil + nsec = int64(float64(nsec) * math.Pow(float64(10), float64(9-len(n)))) + return sec, nsec, nil } diff --git a/vendor/github.com/docker/docker/api/types/types.go b/vendor/github.com/docker/docker/api/types/types.go index 036405299..b413e0200 100644 --- a/vendor/github.com/docker/docker/api/types/types.go +++ b/vendor/github.com/docker/docker/api/types/types.go @@ -123,9 +123,8 @@ type ImageInspect struct { // store images self-contained, and no longer use a parent-chain, making // this field an equivalent of the Size field. // - // This field is kept for backward compatibility, but may be removed in - // a future version of the API. - VirtualSize int64 // TODO(thaJeztah): deprecate this field + // Deprecated: Unused in API 1.43 and up, but kept for backward compatibility with older API versions. + VirtualSize int64 `json:"VirtualSize,omitempty"` // GraphDriver holds information about the storage driver used to store the // container's and image's filesystem. @@ -297,8 +296,6 @@ type Info struct { Labels []string ExperimentalBuild bool ServerVersion string - ClusterStore string `json:",omitempty"` // Deprecated: host-discovery and overlay networks with external k/v stores are deprecated - ClusterAdvertise string `json:",omitempty"` // Deprecated: host-discovery and overlay networks with external k/v stores are deprecated Runtimes map[string]Runtime DefaultRuntime string Swarm swarm.Info @@ -350,20 +347,19 @@ func DecodeSecurityOptions(opts []string) ([]SecurityOpt, error) { continue } secopt := SecurityOpt{} - split := strings.Split(opt, ",") - for _, s := range split { - kv := strings.SplitN(s, "=", 2) - if len(kv) != 2 { + for _, s := range strings.Split(opt, ",") { + k, v, ok := strings.Cut(s, "=") + if !ok { return nil, fmt.Errorf("invalid security option %q", s) } - if kv[0] == "" || kv[1] == "" { + if k == "" || v == "" { return nil, errors.New("invalid empty security option") } - if kv[0] == "name" { - secopt.Name = kv[1] + if k == "name" { + secopt.Name = v continue } - secopt.Options = append(secopt.Options, KeyValue{Key: kv[0], Value: kv[1]}) + secopt.Options = append(secopt.Options, KeyValue{Key: k, Value: v}) } so = append(so, secopt) } @@ -656,12 +652,18 @@ type Checkpoint struct { // Runtime describes an OCI runtime type Runtime struct { - Path string `json:"path"` + // "Legacy" runtime configuration for runc-compatible runtimes. + + Path string `json:"path,omitempty"` Args []string `json:"runtimeArgs,omitempty"` + // Shimv2 runtime configuration. Mutually exclusive with the legacy config above. + + Type string `json:"runtimeType,omitempty"` + Options map[string]interface{} `json:"options,omitempty"` + // This is exposed here only for internal use - // It is not currently supported to specify custom shim configs - Shim *ShimConfig `json:"-"` + ShimConfig *ShimConfig `json:"-"` } // ShimConfig is used by runtime to configure containerd shims diff --git a/vendor/github.com/docker/docker/api/types/versions/compare.go b/vendor/github.com/docker/docker/api/types/versions/compare.go index 489e917ee..621725a36 100644 --- a/vendor/github.com/docker/docker/api/types/versions/compare.go +++ b/vendor/github.com/docker/docker/api/types/versions/compare.go @@ -16,11 +16,11 @@ func compare(v1, v2 string) int { otherTab = strings.Split(v2, ".") ) - max := len(currTab) - if len(otherTab) > max { - max = len(otherTab) + maxVer := len(currTab) + if len(otherTab) > maxVer { + maxVer = len(otherTab) } - for i := 0; i < max; i++ { + for i := 0; i < maxVer; i++ { var currInt, otherInt int if len(currTab) > i { diff --git a/vendor/github.com/docker/docker/api/types/volume/deprecated.go b/vendor/github.com/docker/docker/api/types/volume/deprecated.go deleted file mode 100644 index ab622d8cc..000000000 --- a/vendor/github.com/docker/docker/api/types/volume/deprecated.go +++ /dev/null @@ -1,11 +0,0 @@ -package volume // import "github.com/docker/docker/api/types/volume" - -// VolumeCreateBody Volume configuration -// -// Deprecated: use CreateOptions -type VolumeCreateBody = CreateOptions - -// VolumeListOKBody Volume list response -// -// Deprecated: use ListResponse -type VolumeListOKBody = ListResponse diff --git a/vendor/github.com/docker/docker/client/build_prune.go b/vendor/github.com/docker/docker/client/build_prune.go index 397d67cdc..2b6606236 100644 --- a/vendor/github.com/docker/docker/client/build_prune.go +++ b/vendor/github.com/docker/docker/client/build_prune.go @@ -3,8 +3,8 @@ package client // import "github.com/docker/docker/client" import ( "context" "encoding/json" - "fmt" "net/url" + "strconv" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" @@ -23,12 +23,12 @@ func (cli *Client) BuildCachePrune(ctx context.Context, opts types.BuildCachePru if opts.All { query.Set("all", "1") } - query.Set("keep-storage", fmt.Sprintf("%d", opts.KeepStorage)) - filters, err := filters.ToJSON(opts.Filters) + query.Set("keep-storage", strconv.Itoa(int(opts.KeepStorage))) + f, err := filters.ToJSON(opts.Filters) if err != nil { return nil, errors.Wrap(err, "prune could not marshal filters option") } - query.Set("filters", filters) + query.Set("filters", f) serverResp, err := cli.post(ctx, "/build/prune", query, nil, nil) defer ensureReaderClosed(serverResp) @@ -38,7 +38,7 @@ func (cli *Client) BuildCachePrune(ctx context.Context, opts types.BuildCachePru } if err := json.NewDecoder(serverResp.body).Decode(&report); err != nil { - return nil, fmt.Errorf("Error retrieving disk usage: %v", err) + return nil, errors.Wrap(err, "error retrieving disk usage") } return &report, nil diff --git a/vendor/github.com/docker/docker/client/client.go b/vendor/github.com/docker/docker/client/client.go index 09ea4851f..54fa36cca 100644 --- a/vendor/github.com/docker/docker/client/client.go +++ b/vendor/github.com/docker/docker/client/client.go @@ -56,6 +56,36 @@ import ( "github.com/pkg/errors" ) +// DummyHost is a hostname used for local communication. +// +// It acts as a valid formatted hostname for local connections (such as "unix://" +// or "npipe://") which do not require a hostname. It should never be resolved, +// but uses the special-purpose ".localhost" TLD (as defined in [RFC 2606, Section 2] +// and [RFC 6761, Section 6.3]). +// +// [RFC 7230, Section 5.4] defines that an empty header must be used for such +// cases: +// +// If the authority component is missing or undefined for the target URI, +// then a client MUST send a Host header field with an empty field-value. +// +// However, [Go stdlib] enforces the semantics of HTTP(S) over TCP, does not +// allow an empty header to be used, and requires req.URL.Scheme to be either +// "http" or "https". +// +// For further details, refer to: +// +// - https://github.com/docker/engine-api/issues/189 +// - https://github.com/golang/go/issues/13624 +// - https://github.com/golang/go/issues/61076 +// - https://github.com/moby/moby/issues/45935 +// +// [RFC 2606, Section 2]: https://www.rfc-editor.org/rfc/rfc2606.html#section-2 +// [RFC 6761, Section 6.3]: https://www.rfc-editor.org/rfc/rfc6761#section-6.3 +// [RFC 7230, Section 5.4]: https://datatracker.ietf.org/doc/html/rfc7230#section-5.4 +// [Go stdlib]: https://github.com/golang/go/blob/6244b1946bc2101b01955468f1be502dbadd6807/src/net/http/transport.go#L558-L569 +const DummyHost = "api.moby.localhost" + // ErrRedirect is the error returned by checkRedirect when the request is non-GET. var ErrRedirect = errors.New("unexpected redirect in response") @@ -126,7 +156,12 @@ func CheckRedirect(req *http.Request, via []*http.Request) error { // client.WithAPIVersionNegotiation(), // ) func NewClientWithOpts(ops ...Opt) (*Client, error) { - client, err := defaultHTTPClient(DefaultDockerHost) + hostURL, err := ParseHostURL(DefaultDockerHost) + if err != nil { + return nil, err + } + + client, err := defaultHTTPClient(hostURL) if err != nil { return nil, err } @@ -134,8 +169,8 @@ func NewClientWithOpts(ops ...Opt) (*Client, error) { host: DefaultDockerHost, version: api.DefaultVersion, client: client, - proto: defaultProto, - addr: defaultAddr, + proto: hostURL.Scheme, + addr: hostURL.Host, } for _, op := range ops { @@ -161,13 +196,12 @@ func NewClientWithOpts(ops ...Opt) (*Client, error) { return c, nil } -func defaultHTTPClient(host string) (*http.Client, error) { - hostURL, err := ParseHostURL(host) +func defaultHTTPClient(hostURL *url.URL) (*http.Client, error) { + transport := &http.Transport{} + err := sockets.ConfigureTransport(transport, hostURL.Scheme, hostURL.Host) if err != nil { return nil, err } - transport := &http.Transport{} - _ = sockets.ConfigureTransport(transport, hostURL.Scheme, hostURL.Host) return &http.Client{ Transport: transport, CheckRedirect: CheckRedirect, @@ -283,13 +317,12 @@ func (cli *Client) HTTPClient() *http.Client { // ParseHostURL parses a url string, validates the string is a host url, and // returns the parsed URL func ParseHostURL(host string) (*url.URL, error) { - protoAddrParts := strings.SplitN(host, "://", 2) - if len(protoAddrParts) == 1 { + proto, addr, ok := strings.Cut(host, "://") + if !ok || addr == "" { return nil, errors.Errorf("unable to parse docker host `%s`", host) } var basePath string - proto, addr := protoAddrParts[0], protoAddrParts[1] if proto == "tcp" { parsed, err := url.Parse("tcp://" + addr) if err != nil { diff --git a/vendor/github.com/docker/docker/client/client_unix.go b/vendor/github.com/docker/docker/client/client_unix.go index f0783f708..319b738d3 100644 --- a/vendor/github.com/docker/docker/client/client_unix.go +++ b/vendor/github.com/docker/docker/client/client_unix.go @@ -1,11 +1,8 @@ -//go:build linux || freebsd || openbsd || netbsd || darwin || solaris || illumos || dragonfly -// +build linux freebsd openbsd netbsd darwin solaris illumos dragonfly +//go:build !windows +// +build !windows package client // import "github.com/docker/docker/client" // DefaultDockerHost defines OS-specific default host if the DOCKER_HOST // (EnvOverrideHost) environment variable is unset or empty. const DefaultDockerHost = "unix:///var/run/docker.sock" - -const defaultProto = "unix" -const defaultAddr = "/var/run/docker.sock" diff --git a/vendor/github.com/docker/docker/client/client_windows.go b/vendor/github.com/docker/docker/client/client_windows.go index 5abe60457..56572d1a2 100644 --- a/vendor/github.com/docker/docker/client/client_windows.go +++ b/vendor/github.com/docker/docker/client/client_windows.go @@ -3,6 +3,3 @@ package client // import "github.com/docker/docker/client" // DefaultDockerHost defines OS-specific default host if the DOCKER_HOST // (EnvOverrideHost) environment variable is unset or empty. const DefaultDockerHost = "npipe:////./pipe/docker_engine" - -const defaultProto = "npipe" -const defaultAddr = "//./pipe/docker_engine" diff --git a/vendor/github.com/docker/docker/client/container_create.go b/vendor/github.com/docker/docker/client/container_create.go index f82420b67..193a2bb56 100644 --- a/vendor/github.com/docker/docker/client/container_create.go +++ b/vendor/github.com/docker/docker/client/container_create.go @@ -9,7 +9,7 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/versions" - specs "github.com/opencontainers/image-spec/specs-go/v1" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) type configWrapper struct { @@ -20,7 +20,7 @@ type configWrapper struct { // ContainerCreate creates a new container based on the given configuration. // It can be associated with a name, but it's not mandatory. -func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (container.CreateResponse, error) { +func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) { var response container.CreateResponse if err := cli.NewVersionError("1.25", "stop timeout"); config != nil && config.StopTimeout != nil && err != nil { @@ -75,7 +75,7 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config // Similar to containerd's platforms.Format(), but does allow components to be // omitted (e.g. pass "architecture" only, without "os": // https://github.com/containerd/containerd/blob/v1.5.2/platforms/platforms.go#L243-L263 -func formatPlatform(platform *specs.Platform) string { +func formatPlatform(platform *ocispec.Platform) string { if platform == nil { return "" } diff --git a/vendor/github.com/docker/docker/client/container_diff.go b/vendor/github.com/docker/docker/client/container_diff.go index 29dac8491..c22c819a7 100644 --- a/vendor/github.com/docker/docker/client/container_diff.go +++ b/vendor/github.com/docker/docker/client/container_diff.go @@ -9,8 +9,8 @@ import ( ) // ContainerDiff shows differences in a container filesystem since it was started. -func (cli *Client) ContainerDiff(ctx context.Context, containerID string) ([]container.ContainerChangeResponseItem, error) { - var changes []container.ContainerChangeResponseItem +func (cli *Client) ContainerDiff(ctx context.Context, containerID string) ([]container.FilesystemChange, error) { + var changes []container.FilesystemChange serverResp, err := cli.get(ctx, "/containers/"+containerID+"/changes", url.Values{}, nil) defer ensureReaderClosed(serverResp) diff --git a/vendor/github.com/docker/docker/client/distribution_inspect.go b/vendor/github.com/docker/docker/client/distribution_inspect.go index 7f36c99a0..efab066d3 100644 --- a/vendor/github.com/docker/docker/client/distribution_inspect.go +++ b/vendor/github.com/docker/docker/client/distribution_inspect.go @@ -5,13 +5,13 @@ import ( "encoding/json" "net/url" - registrytypes "github.com/docker/docker/api/types/registry" + "github.com/docker/docker/api/types/registry" ) // DistributionInspect returns the image digest with the full manifest. -func (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegistryAuth string) (registrytypes.DistributionInspect, error) { +func (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegistryAuth string) (registry.DistributionInspect, error) { // Contact the registry to retrieve digest and platform information - var distributionInspect registrytypes.DistributionInspect + var distributionInspect registry.DistributionInspect if image == "" { return distributionInspect, objectNotFoundError{object: "distribution", id: image} } @@ -23,7 +23,7 @@ func (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegist if encodedRegistryAuth != "" { headers = map[string][]string{ - "X-Registry-Auth": {encodedRegistryAuth}, + registry.AuthHeader: {encodedRegistryAuth}, } } diff --git a/vendor/github.com/docker/docker/client/errors.go b/vendor/github.com/docker/docker/client/errors.go index e5a8a865f..6878144c4 100644 --- a/vendor/github.com/docker/docker/client/errors.go +++ b/vendor/github.com/docker/docker/client/errors.go @@ -58,31 +58,6 @@ func (e objectNotFoundError) Error() string { return fmt.Sprintf("Error: No such %s: %s", e.object, e.id) } -// IsErrUnauthorized returns true if the error is caused -// when a remote registry authentication fails -// -// Deprecated: use errdefs.IsUnauthorized -func IsErrUnauthorized(err error) bool { - return errdefs.IsUnauthorized(err) -} - -type pluginPermissionDenied struct { - name string -} - -func (e pluginPermissionDenied) Error() string { - return "Permission denied while installing plugin " + e.name -} - -// IsErrNotImplemented returns true if the error is a NotImplemented error. -// This is returned by the API when a requested feature has not been -// implemented. -// -// Deprecated: use errdefs.IsNotImplemented -func IsErrNotImplemented(err error) bool { - return errdefs.IsNotImplemented(err) -} - // NewVersionError returns an error if the APIVersion required // if less than the current supported version func (cli *Client) NewVersionError(APIrequired, feature string) error { diff --git a/vendor/github.com/docker/docker/client/hijack.go b/vendor/github.com/docker/docker/client/hijack.go index 6bdacab10..7e84865f6 100644 --- a/vendor/github.com/docker/docker/client/hijack.go +++ b/vendor/github.com/docker/docker/client/hijack.go @@ -23,14 +23,10 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu if err != nil { return types.HijackedResponse{}, err } - - apiPath := cli.getAPIPath(ctx, path, query) - req, err := http.NewRequest(http.MethodPost, apiPath, bodyEncoded) + req, err := cli.buildRequest(http.MethodPost, cli.getAPIPath(ctx, path, query), bodyEncoded, headers) if err != nil { return types.HijackedResponse{}, err } - req = cli.addHeaders(req, headers) - conn, mediaType, err := cli.setupHijackConn(ctx, req, "tcp") if err != nil { return types.HijackedResponse{}, err @@ -64,7 +60,6 @@ func fallbackDial(proto, addr string, tlsConfig *tls.Config) (net.Conn, error) { } func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto string) (net.Conn, string, error) { - req.Host = cli.addr req.Header.Set("Connection", "Upgrade") req.Header.Set("Upgrade", proto) @@ -80,8 +75,8 @@ func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto // state. Setting TCP KeepAlive on the socket connection will prohibit // ECONNTIMEOUT unless the socket connection truly is broken if tcpConn, ok := conn.(*net.TCPConn); ok { - tcpConn.SetKeepAlive(true) - tcpConn.SetKeepAlivePeriod(30 * time.Second) + _ = tcpConn.SetKeepAlive(true) + _ = tcpConn.SetKeepAlivePeriod(30 * time.Second) } clientconn := httputil.NewClientConn(conn, nil) @@ -96,7 +91,7 @@ func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto return nil, "", err } if resp.StatusCode != http.StatusSwitchingProtocols { - resp.Body.Close() + _ = resp.Body.Close() return nil, "", fmt.Errorf("unable to upgrade to %s, received %d", proto, resp.StatusCode) } } diff --git a/vendor/github.com/docker/docker/client/image_create.go b/vendor/github.com/docker/docker/client/image_create.go index b1c022777..6a9b708f7 100644 --- a/vendor/github.com/docker/docker/client/image_create.go +++ b/vendor/github.com/docker/docker/client/image_create.go @@ -8,6 +8,7 @@ import ( "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/registry" ) // ImageCreate creates a new image based on the parent options. @@ -32,6 +33,6 @@ func (cli *Client) ImageCreate(ctx context.Context, parentReference string, opti } func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) { - headers := map[string][]string{"X-Registry-Auth": {registryAuth}} + headers := map[string][]string{registry.AuthHeader: {registryAuth}} return cli.post(ctx, "/images/create", query, nil, headers) } diff --git a/vendor/github.com/docker/docker/client/image_push.go b/vendor/github.com/docker/docker/client/image_push.go index 845580d4a..dd1b8f347 100644 --- a/vendor/github.com/docker/docker/client/image_push.go +++ b/vendor/github.com/docker/docker/client/image_push.go @@ -8,6 +8,7 @@ import ( "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/registry" "github.com/docker/docker/errdefs" ) @@ -49,6 +50,6 @@ func (cli *Client) ImagePush(ctx context.Context, image string, options types.Im } func (cli *Client) tryImagePush(ctx context.Context, imageID string, query url.Values, registryAuth string) (serverResponse, error) { - headers := map[string][]string{"X-Registry-Auth": {registryAuth}} + headers := map[string][]string{registry.AuthHeader: {registryAuth}} return cli.post(ctx, "/images/"+imageID+"/push", query, nil, headers) } diff --git a/vendor/github.com/docker/docker/client/image_search.go b/vendor/github.com/docker/docker/client/image_search.go index e69fa3722..5f0c49ed3 100644 --- a/vendor/github.com/docker/docker/client/image_search.go +++ b/vendor/github.com/docker/docker/client/image_search.go @@ -48,6 +48,6 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options types.I } func (cli *Client) tryImageSearch(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) { - headers := map[string][]string{"X-Registry-Auth": {registryAuth}} + headers := map[string][]string{registry.AuthHeader: {registryAuth}} return cli.get(ctx, "/images/search", query, headers) } diff --git a/vendor/github.com/docker/docker/client/interface.go b/vendor/github.com/docker/docker/client/interface.go index e9c1ed722..7993c5a48 100644 --- a/vendor/github.com/docker/docker/client/interface.go +++ b/vendor/github.com/docker/docker/client/interface.go @@ -15,7 +15,7 @@ import ( "github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/volume" - specs "github.com/opencontainers/image-spec/specs-go/v1" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) // CommonAPIClient is the common methods between stable and experimental versions of APIClient. @@ -47,8 +47,8 @@ type CommonAPIClient interface { type ContainerAPIClient interface { ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error) ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.IDResponse, error) - ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (container.CreateResponse, error) - ContainerDiff(ctx context.Context, container string) ([]container.ContainerChangeResponseItem, error) + ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) + ContainerDiff(ctx context.Context, container string) ([]container.FilesystemChange, error) ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error) ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error) ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error) @@ -166,7 +166,7 @@ type SwarmAPIClient interface { type SystemAPIClient interface { Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error) Info(ctx context.Context) (types.Info, error) - RegistryLogin(ctx context.Context, auth types.AuthConfig) (registry.AuthenticateOKBody, error) + RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error) DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error) Ping(ctx context.Context) (types.Ping, error) } @@ -176,7 +176,7 @@ type VolumeAPIClient interface { VolumeCreate(ctx context.Context, options volume.CreateOptions) (volume.Volume, error) VolumeInspect(ctx context.Context, volumeID string) (volume.Volume, error) VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error) - VolumeList(ctx context.Context, filter filters.Args) (volume.ListResponse, error) + VolumeList(ctx context.Context, options volume.ListOptions) (volume.ListResponse, error) VolumeRemove(ctx context.Context, volumeID string, force bool) error VolumesPrune(ctx context.Context, pruneFilter filters.Args) (types.VolumesPruneReport, error) VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error diff --git a/vendor/github.com/docker/docker/client/login.go b/vendor/github.com/docker/docker/client/login.go index f05852063..19e985e0b 100644 --- a/vendor/github.com/docker/docker/client/login.go +++ b/vendor/github.com/docker/docker/client/login.go @@ -5,13 +5,12 @@ import ( "encoding/json" "net/url" - "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/registry" ) // RegistryLogin authenticates the docker server with a given docker registry. // It returns unauthorizedError when the authentication fails. -func (cli *Client) RegistryLogin(ctx context.Context, auth types.AuthConfig) (registry.AuthenticateOKBody, error) { +func (cli *Client) RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error) { resp, err := cli.post(ctx, "/auth", url.Values{}, auth, nil) defer ensureReaderClosed(resp) diff --git a/vendor/github.com/docker/docker/client/ping.go b/vendor/github.com/docker/docker/client/ping.go index 27e8695cb..347ae71e0 100644 --- a/vendor/github.com/docker/docker/client/ping.go +++ b/vendor/github.com/docker/docker/client/ping.go @@ -64,10 +64,10 @@ func parsePingResponse(cli *Client, resp serverResponse) (types.Ping, error) { ping.BuilderVersion = types.BuilderVersion(bv) } if si := resp.header.Get("Swarm"); si != "" { - parts := strings.SplitN(si, "/", 2) + state, role, _ := strings.Cut(si, "/") ping.SwarmStatus = &swarm.Status{ - NodeState: swarm.LocalNodeState(parts[0]), - ControlAvailable: len(parts) == 2 && parts[1] == "manager", + NodeState: swarm.LocalNodeState(state), + ControlAvailable: role == "manager", } } err := cli.checkResponseErr(resp) diff --git a/vendor/github.com/docker/docker/client/plugin_install.go b/vendor/github.com/docker/docker/client/plugin_install.go index 012afe61c..3a740ec4f 100644 --- a/vendor/github.com/docker/docker/client/plugin_install.go +++ b/vendor/github.com/docker/docker/client/plugin_install.go @@ -8,6 +8,7 @@ import ( "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/registry" "github.com/docker/docker/errdefs" "github.com/pkg/errors" ) @@ -67,12 +68,12 @@ func (cli *Client) PluginInstall(ctx context.Context, name string, options types } func (cli *Client) tryPluginPrivileges(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) { - headers := map[string][]string{"X-Registry-Auth": {registryAuth}} + headers := map[string][]string{registry.AuthHeader: {registryAuth}} return cli.get(ctx, "/plugins/privileges", query, headers) } func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, privileges types.PluginPrivileges, registryAuth string) (serverResponse, error) { - headers := map[string][]string{"X-Registry-Auth": {registryAuth}} + headers := map[string][]string{registry.AuthHeader: {registryAuth}} return cli.post(ctx, "/plugins/pull", query, privileges, headers) } @@ -106,7 +107,7 @@ func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values, return nil, err } if !accept { - return nil, pluginPermissionDenied{options.RemoteRef} + return nil, errors.Errorf("permission denied while installing plugin %s", options.RemoteRef) } } return privileges, nil diff --git a/vendor/github.com/docker/docker/client/plugin_push.go b/vendor/github.com/docker/docker/client/plugin_push.go index d20bfe844..18f9754c4 100644 --- a/vendor/github.com/docker/docker/client/plugin_push.go +++ b/vendor/github.com/docker/docker/client/plugin_push.go @@ -3,11 +3,13 @@ package client // import "github.com/docker/docker/client" import ( "context" "io" + + "github.com/docker/docker/api/types/registry" ) // PluginPush pushes a plugin to a registry func (cli *Client) PluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error) { - headers := map[string][]string{"X-Registry-Auth": {registryAuth}} + headers := map[string][]string{registry.AuthHeader: {registryAuth}} resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, nil, headers) if err != nil { return nil, err diff --git a/vendor/github.com/docker/docker/client/plugin_upgrade.go b/vendor/github.com/docker/docker/client/plugin_upgrade.go index 115cea945..995d1fd2c 100644 --- a/vendor/github.com/docker/docker/client/plugin_upgrade.go +++ b/vendor/github.com/docker/docker/client/plugin_upgrade.go @@ -7,6 +7,7 @@ import ( "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/registry" "github.com/pkg/errors" ) @@ -34,6 +35,6 @@ func (cli *Client) PluginUpgrade(ctx context.Context, name string, options types } func (cli *Client) tryPluginUpgrade(ctx context.Context, query url.Values, privileges types.PluginPrivileges, name, registryAuth string) (serverResponse, error) { - headers := map[string][]string{"X-Registry-Auth": {registryAuth}} + headers := map[string][]string{registry.AuthHeader: {registryAuth}} return cli.post(ctx, "/plugins/"+name+"/upgrade", query, privileges, headers) } diff --git a/vendor/github.com/docker/docker/client/request.go b/vendor/github.com/docker/docker/client/request.go index c799095c1..bcedcf3bd 100644 --- a/vendor/github.com/docker/docker/client/request.go +++ b/vendor/github.com/docker/docker/client/request.go @@ -96,16 +96,14 @@ func (cli *Client) buildRequest(method, path string, body io.Reader, headers hea return nil, err } req = cli.addHeaders(req, headers) + req.URL.Scheme = cli.scheme + req.URL.Host = cli.addr if cli.proto == "unix" || cli.proto == "npipe" { - // For local communications, it doesn't matter what the host is. We just - // need a valid and meaningful host name. (See #189) - req.Host = "docker" + // Override host header for non-tcp connections. + req.Host = DummyHost } - req.URL.Host = cli.addr - req.URL.Scheme = cli.scheme - if expectedPayload && req.Header.Get("Content-Type") == "" { req.Header.Set("Content-Type", "text/plain") } diff --git a/vendor/github.com/docker/docker/client/service_create.go b/vendor/github.com/docker/docker/client/service_create.go index 23024d0f8..b6065b8ee 100644 --- a/vendor/github.com/docker/docker/client/service_create.go +++ b/vendor/github.com/docker/docker/client/service_create.go @@ -8,6 +8,7 @@ import ( "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/swarm" "github.com/opencontainers/go-digest" "github.com/pkg/errors" @@ -21,7 +22,7 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, } if options.EncodedRegistryAuth != "" { - headers["X-Registry-Auth"] = []string{options.EncodedRegistryAuth} + headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth} } // Make sure containerSpec is not nil when no runtime is set or the runtime is set to container diff --git a/vendor/github.com/docker/docker/client/service_update.go b/vendor/github.com/docker/docker/client/service_update.go index 8014b8625..ff8cded8b 100644 --- a/vendor/github.com/docker/docker/client/service_update.go +++ b/vendor/github.com/docker/docker/client/service_update.go @@ -6,6 +6,7 @@ import ( "net/url" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/swarm" ) @@ -23,7 +24,7 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version } if options.EncodedRegistryAuth != "" { - headers["X-Registry-Auth"] = []string{options.EncodedRegistryAuth} + headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth} } if options.RegistryAuthFrom != "" { diff --git a/vendor/github.com/docker/docker/client/volume_list.go b/vendor/github.com/docker/docker/client/volume_list.go index d8204f8db..d5ea9827c 100644 --- a/vendor/github.com/docker/docker/client/volume_list.go +++ b/vendor/github.com/docker/docker/client/volume_list.go @@ -10,13 +10,13 @@ import ( ) // VolumeList returns the volumes configured in the docker host. -func (cli *Client) VolumeList(ctx context.Context, filter filters.Args) (volume.ListResponse, error) { +func (cli *Client) VolumeList(ctx context.Context, options volume.ListOptions) (volume.ListResponse, error) { var volumes volume.ListResponse query := url.Values{} - if filter.Len() > 0 { + if options.Filters.Len() > 0 { //nolint:staticcheck // ignore SA1019 for old code - filterJSON, err := filters.ToParamWithVersion(cli.version, filter) + filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters) if err != nil { return volumes, err } diff --git a/vendor/github.com/docker/docker/pkg/homedir/homedir_linux.go b/vendor/github.com/docker/docker/pkg/homedir/homedir_linux.go index 7df039b4c..ded1c7c8c 100644 --- a/vendor/github.com/docker/docker/pkg/homedir/homedir_linux.go +++ b/vendor/github.com/docker/docker/pkg/homedir/homedir_linux.go @@ -64,13 +64,14 @@ func stick(f string) error { // GetDataHome returns XDG_DATA_HOME. // GetDataHome returns $HOME/.local/share and nil error if XDG_DATA_HOME is not set. +// If HOME and XDG_DATA_HOME are not set, getpwent(3) is consulted to determine the users home directory. // // See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html func GetDataHome() (string, error) { if xdgDataHome := os.Getenv("XDG_DATA_HOME"); xdgDataHome != "" { return xdgDataHome, nil } - home := os.Getenv("HOME") + home := Get() if home == "" { return "", errors.New("could not get either XDG_DATA_HOME or HOME") } @@ -79,13 +80,14 @@ func GetDataHome() (string, error) { // GetConfigHome returns XDG_CONFIG_HOME. // GetConfigHome returns $HOME/.config and nil error if XDG_CONFIG_HOME is not set. +// If HOME and XDG_CONFIG_HOME are not set, getpwent(3) is consulted to determine the users home directory. // // See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html func GetConfigHome() (string, error) { if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" { return xdgConfigHome, nil } - home := os.Getenv("HOME") + home := Get() if home == "" { return "", errors.New("could not get either XDG_CONFIG_HOME or HOME") } @@ -93,8 +95,9 @@ func GetConfigHome() (string, error) { } // GetLibHome returns $HOME/.local/lib +// If HOME is not set, getpwent(3) is consulted to determine the users home directory. func GetLibHome() (string, error) { - home := os.Getenv("HOME") + home := Get() if home == "" { return "", errors.New("could not get HOME") } diff --git a/vendor/github.com/docker/docker/pkg/ioutils/temp_unix.go b/vendor/github.com/docker/docker/pkg/ioutils/temp_unix.go deleted file mode 100644 index 748912230..000000000 --- a/vendor/github.com/docker/docker/pkg/ioutils/temp_unix.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build !windows -// +build !windows - -package ioutils // import "github.com/docker/docker/pkg/ioutils" - -import "os" - -// TempDir on Unix systems is equivalent to os.MkdirTemp. -func TempDir(dir, prefix string) (string, error) { - return os.MkdirTemp(dir, prefix) -} diff --git a/vendor/github.com/docker/docker/pkg/ioutils/temp_windows.go b/vendor/github.com/docker/docker/pkg/ioutils/temp_windows.go deleted file mode 100644 index a57fd9af6..000000000 --- a/vendor/github.com/docker/docker/pkg/ioutils/temp_windows.go +++ /dev/null @@ -1,16 +0,0 @@ -package ioutils // import "github.com/docker/docker/pkg/ioutils" - -import ( - "os" - - "github.com/docker/docker/pkg/longpath" -) - -// TempDir is the equivalent of os.MkdirTemp, except that the result is in Windows longpath format. -func TempDir(dir, prefix string) (string, error) { - tempDir, err := os.MkdirTemp(dir, prefix) - if err != nil { - return "", err - } - return longpath.AddPrefix(tempDir), nil -} diff --git a/vendor/github.com/docker/docker/pkg/ioutils/tempdir_deprecated.go b/vendor/github.com/docker/docker/pkg/ioutils/tempdir_deprecated.go new file mode 100644 index 000000000..b3321602c --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/ioutils/tempdir_deprecated.go @@ -0,0 +1,10 @@ +package ioutils + +import "github.com/docker/docker/pkg/longpath" + +// TempDir is the equivalent of [os.MkdirTemp], except that on Windows +// the result is in Windows longpath format. On Unix systems it is +// equivalent to [os.MkdirTemp]. +// +// Deprecated: use [longpath.MkdirTemp]. +var TempDir = longpath.MkdirTemp diff --git a/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go b/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go index cf8d04b1b..035160c83 100644 --- a/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go +++ b/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go @@ -16,8 +16,8 @@ import ( // ensure the formatted time isalways the same number of characters. const RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" -// JSONError wraps a concrete Code and Message, `Code` is -// is an integer error code, `Message` is the error message. +// JSONError wraps a concrete Code and Message, Code is +// an integer error code, Message is the error message. type JSONError struct { Code int `json:"code,omitempty"` Message string `json:"message,omitempty"` @@ -27,20 +27,28 @@ func (e *JSONError) Error() string { return e.Message } -// JSONProgress describes a Progress. terminalFd is the fd of the current terminal, -// Start is the initial value for the operation. Current is the current status and -// value of the progress made towards Total. Total is the end value describing when -// we made 100% progress for an operation. +// JSONProgress describes a progress message in a JSON stream. type JSONProgress struct { + // Current is the current status and value of the progress made towards Total. + Current int64 `json:"current,omitempty"` + // Total is the end value describing when we made 100% progress for an operation. + Total int64 `json:"total,omitempty"` + // Start is the initial value for the operation. + Start int64 `json:"start,omitempty"` + // HideCounts. if true, hides the progress count indicator (xB/yB). + HideCounts bool `json:"hidecounts,omitempty"` + // Units is the unit to print for progress. It defaults to "bytes" if empty. + Units string `json:"units,omitempty"` + + // terminalFd is the fd of the current terminal, if any. It is used + // to get the terminal width. terminalFd uintptr - Current int64 `json:"current,omitempty"` - Total int64 `json:"total,omitempty"` - Start int64 `json:"start,omitempty"` - // If true, don't show xB/yB - HideCounts bool `json:"hidecounts,omitempty"` - Units string `json:"units,omitempty"` - nowFunc func() time.Time - winSize int + + // nowFunc is used to override the current time in tests. + nowFunc func() time.Time + + // winSize is used to override the terminal width in tests. + winSize int } func (p *JSONProgress) String() string { @@ -56,8 +64,7 @@ func (p *JSONProgress) String() string { if p.Total <= 0 { switch p.Units { case "": - current := units.HumanSize(float64(p.Current)) - return fmt.Sprintf("%8v", current) + return fmt.Sprintf("%8v", units.HumanSize(float64(p.Current))) default: return fmt.Sprintf("%d %s", p.Current, p.Units) } @@ -110,17 +117,17 @@ func (p *JSONProgress) String() string { return pbBox + numbersBox + timeLeftBox } -// shim for testing +// now returns the current time in UTC, but can be overridden in tests +// by setting JSONProgress.nowFunc to a custom function. func (p *JSONProgress) now() time.Time { - if p.nowFunc == nil { - p.nowFunc = func() time.Time { - return time.Now().UTC() - } + if p.nowFunc != nil { + return p.nowFunc() } - return p.nowFunc() + return time.Now().UTC() } -// shim for testing +// width returns the current terminal's width, but can be overridden +// in tests by setting JSONProgress.winSize to a non-zero value. func (p *JSONProgress) width() int { if p.winSize != 0 { return p.winSize @@ -164,13 +171,11 @@ func cursorDown(out io.Writer, l uint) { fmt.Fprint(out, aec.Down(l)) } -// Display displays the JSONMessage to `out`. If `isTerminal` is true, it will erase the -// entire current line when displaying the progressbar. +// Display prints the JSONMessage to out. If isTerminal is true, it erases +// the entire current line when displaying the progressbar. It returns an +// error if the [JSONMessage.Error] field is non-nil. func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error { if jm.Error != nil { - if jm.Error.Code == 401 { - return fmt.Errorf("authentication is required") - } return jm.Error } var endl string @@ -204,9 +209,22 @@ func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error { return nil } -// DisplayJSONMessagesStream displays a json message stream from `in` to `out`, `isTerminal` -// describes if `out` is a terminal. If this is the case, it will print `\n` at the end of -// each line and move the cursor while displaying. +// DisplayJSONMessagesStream reads a JSON message stream from in, and writes +// each [JSONMessage] to out. It returns an error if an invalid JSONMessage +// is received, or if a JSONMessage containers a non-zero [JSONMessage.Error]. +// +// Presentation of the JSONMessage depends on whether a terminal is attached, +// and on the terminal width. Progress bars ([JSONProgress]) are suppressed +// on narrower terminals (< 110 characters). +// +// - isTerminal describes if out is a terminal, in which case it prints +// a newline ("\n") at the end of each line and moves the cursor while +// displaying. +// - terminalFd is the fd of the current terminal (if any), and used +// to get the terminal width. +// - auxCallback allows handling the [JSONMessage.Aux] field. It is +// called if a JSONMessage contains an Aux field, in which case +// DisplayJSONMessagesStream does not present the JSONMessage. func DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr, isTerminal bool, auxCallback func(JSONMessage)) error { var ( dec = json.NewDecoder(in) @@ -271,13 +289,19 @@ func DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr, return nil } -type stream interface { +// Stream is an io.Writer for output with utilities to get the output's file +// descriptor and to detect wether it's a terminal. +// +// it is subset of the streams.Out type in +// https://pkg.go.dev/github.com/docker/cli@v20.10.17+incompatible/cli/streams#Out +type Stream interface { io.Writer FD() uintptr IsTerminal() bool } -// DisplayJSONMessagesToStream prints json messages to the output stream -func DisplayJSONMessagesToStream(in io.Reader, stream stream, auxCallback func(JSONMessage)) error { +// DisplayJSONMessagesToStream prints json messages to the output Stream. It is +// used by the Docker CLI to print JSONMessage streams. +func DisplayJSONMessagesToStream(in io.Reader, stream Stream, auxCallback func(JSONMessage)) error { return DisplayJSONMessagesStream(in, stream, stream.FD(), stream.IsTerminal(), auxCallback) } diff --git a/vendor/github.com/docker/docker/pkg/longpath/longpath.go b/vendor/github.com/docker/docker/pkg/longpath/longpath.go index 4177affba..1c5dde521 100644 --- a/vendor/github.com/docker/docker/pkg/longpath/longpath.go +++ b/vendor/github.com/docker/docker/pkg/longpath/longpath.go @@ -1,17 +1,20 @@ -// longpath introduces some constants and helper functions for handling long paths -// in Windows, which are expected to be prepended with `\\?\` and followed by either -// a drive letter, a UNC server\share, or a volume identifier. - +// Package longpath introduces some constants and helper functions for handling +// long paths in Windows. +// +// Long paths are expected to be prepended with "\\?\" and followed by either a +// drive letter, a UNC server\share, or a volume identifier. package longpath // import "github.com/docker/docker/pkg/longpath" import ( + "os" + "runtime" "strings" ) // Prefix is the longpath prefix for Windows file paths. const Prefix = `\\?\` -// AddPrefix will add the Windows long path prefix to the path provided if +// AddPrefix adds the Windows long path prefix to the path provided if // it does not already have it. func AddPrefix(path string) string { if !strings.HasPrefix(path, Prefix) { @@ -24,3 +27,17 @@ func AddPrefix(path string) string { } return path } + +// MkdirTemp is the equivalent of [os.MkdirTemp], except that on Windows +// the result is in Windows longpath format. On Unix systems it is +// equivalent to [os.MkdirTemp]. +func MkdirTemp(dir, prefix string) (string, error) { + tempDir, err := os.MkdirTemp(dir, prefix) + if err != nil { + return "", err + } + if runtime.GOOS != "windows" { + return tempDir, nil + } + return AddPrefix(tempDir), nil +} diff --git a/vendor/github.com/docker/docker/registry/auth.go b/vendor/github.com/docker/docker/registry/auth.go index 38f41db22..dd75a49f3 100644 --- a/vendor/github.com/docker/docker/registry/auth.go +++ b/vendor/github.com/docker/docker/registry/auth.go @@ -9,7 +9,6 @@ import ( "github.com/docker/distribution/registry/client/auth" "github.com/docker/distribution/registry/client/auth/challenge" "github.com/docker/distribution/registry/client/transport" - "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/registry" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -19,7 +18,7 @@ import ( const AuthClientID = "docker" type loginCredentialStore struct { - authConfig *types.AuthConfig + authConfig *registry.AuthConfig } func (lcs loginCredentialStore) Basic(*url.URL) (string, string) { @@ -35,12 +34,12 @@ func (lcs loginCredentialStore) SetRefreshToken(u *url.URL, service, token strin } type staticCredentialStore struct { - auth *types.AuthConfig + auth *registry.AuthConfig } // NewStaticCredentialStore returns a credential store // which always returns the same credential values. -func NewStaticCredentialStore(auth *types.AuthConfig) auth.CredentialStore { +func NewStaticCredentialStore(auth *registry.AuthConfig) auth.CredentialStore { return staticCredentialStore{ auth: auth, } @@ -66,7 +65,7 @@ func (scs staticCredentialStore) SetRefreshToken(*url.URL, string, string) { // loginV2 tries to login to the v2 registry server. The given registry // endpoint will be pinged to get authorization challenges. These challenges // will be used to authenticate against the registry to validate credentials. -func loginV2(authConfig *types.AuthConfig, endpoint APIEndpoint, userAgent string) (string, string, error) { +func loginV2(authConfig *registry.AuthConfig, endpoint APIEndpoint, userAgent string) (string, string, error) { var ( endpointStr = strings.TrimRight(endpoint.URL.String(), "/") + "/v2/" modifiers = Headers(userAgent, nil) @@ -138,7 +137,7 @@ func ConvertToHostname(url string) string { } // ResolveAuthConfig matches an auth configuration to a server address or a URL -func ResolveAuthConfig(authConfigs map[string]types.AuthConfig, index *registry.IndexInfo) types.AuthConfig { +func ResolveAuthConfig(authConfigs map[string]registry.AuthConfig, index *registry.IndexInfo) registry.AuthConfig { configKey := GetAuthConfigKey(index) // First try the happy case if c, found := authConfigs[configKey]; found || index.Official { @@ -154,7 +153,7 @@ func ResolveAuthConfig(authConfigs map[string]types.AuthConfig, index *registry. } // When all else fails, return an empty auth config - return types.AuthConfig{} + return registry.AuthConfig{} } // PingResponseError is used when the response from a ping diff --git a/vendor/github.com/docker/docker/registry/endpoint_v1.go b/vendor/github.com/docker/docker/registry/endpoint_v1.go index c7e930c8a..56257dc79 100644 --- a/vendor/github.com/docker/docker/registry/endpoint_v1.go +++ b/vendor/github.com/docker/docker/registry/endpoint_v1.go @@ -35,13 +35,13 @@ type v1Endpoint struct { // newV1Endpoint parses the given address to return a registry endpoint. // TODO: remove. This is only used by search. -func newV1Endpoint(index *registry.IndexInfo, userAgent string, metaHeaders http.Header) (*v1Endpoint, error) { +func newV1Endpoint(index *registry.IndexInfo, headers http.Header) (*v1Endpoint, error) { tlsConfig, err := newTLSConfig(index.Name, index.Secure) if err != nil { return nil, err } - endpoint, err := newV1EndpointFromStr(GetAuthConfigKey(index), tlsConfig, userAgent, metaHeaders) + endpoint, err := newV1EndpointFromStr(GetAuthConfigKey(index), tlsConfig, headers) if err != nil { return nil, err } @@ -100,7 +100,7 @@ func trimV1Address(address string) (string, error) { return address, nil } -func newV1EndpointFromStr(address string, tlsConfig *tls.Config, userAgent string, metaHeaders http.Header) (*v1Endpoint, error) { +func newV1EndpointFromStr(address string, tlsConfig *tls.Config, headers http.Header) (*v1Endpoint, error) { if !strings.HasPrefix(address, "http://") && !strings.HasPrefix(address, "https://") { address = "https://" + address } @@ -121,7 +121,7 @@ func newV1EndpointFromStr(address string, tlsConfig *tls.Config, userAgent strin return &v1Endpoint{ IsSecure: tlsConfig == nil || !tlsConfig.InsecureSkipVerify, URL: uri, - client: httpClient(transport.NewTransport(tr, Headers(userAgent, metaHeaders)...)), + client: httpClient(transport.NewTransport(tr, Headers("", headers)...)), }, nil } diff --git a/vendor/github.com/docker/docker/registry/search.go b/vendor/github.com/docker/docker/registry/search.go new file mode 100644 index 000000000..60b86ea22 --- /dev/null +++ b/vendor/github.com/docker/docker/registry/search.go @@ -0,0 +1,139 @@ +package registry // import "github.com/docker/docker/registry" + +import ( + "context" + "net/http" + "strconv" + "strings" + + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/registry" + "github.com/docker/docker/errdefs" + + "github.com/docker/distribution/registry/client/auth" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +var acceptedSearchFilterTags = map[string]bool{ + "is-automated": true, + "is-official": true, + "stars": true, +} + +// Search queries the public registry for repositories matching the specified +// search term and filters. +func (s *Service) Search(ctx context.Context, searchFilters filters.Args, term string, limit int, authConfig *registry.AuthConfig, headers map[string][]string) ([]registry.SearchResult, error) { + if err := searchFilters.Validate(acceptedSearchFilterTags); err != nil { + return nil, err + } + + isAutomated, err := searchFilters.GetBoolOrDefault("is-automated", false) + if err != nil { + return nil, err + } + isOfficial, err := searchFilters.GetBoolOrDefault("is-official", false) + if err != nil { + return nil, err + } + + hasStarFilter := 0 + if searchFilters.Contains("stars") { + hasStars := searchFilters.Get("stars") + for _, hasStar := range hasStars { + iHasStar, err := strconv.Atoi(hasStar) + if err != nil { + return nil, errdefs.InvalidParameter(errors.Wrapf(err, "invalid filter 'stars=%s'", hasStar)) + } + if iHasStar > hasStarFilter { + hasStarFilter = iHasStar + } + } + } + + unfilteredResult, err := s.searchUnfiltered(ctx, term, limit, authConfig, headers) + if err != nil { + return nil, err + } + + filteredResults := []registry.SearchResult{} + for _, result := range unfilteredResult.Results { + if searchFilters.Contains("is-automated") { + if isAutomated != result.IsAutomated { + continue + } + } + if searchFilters.Contains("is-official") { + if isOfficial != result.IsOfficial { + continue + } + } + if searchFilters.Contains("stars") { + if result.StarCount < hasStarFilter { + continue + } + } + filteredResults = append(filteredResults, result) + } + + return filteredResults, nil +} + +func (s *Service) searchUnfiltered(ctx context.Context, term string, limit int, authConfig *registry.AuthConfig, headers http.Header) (*registry.SearchResults, error) { + // TODO Use ctx when searching for repositories + if hasScheme(term) { + return nil, invalidParamf("invalid repository name: repository name (%s) should not have a scheme", term) + } + + indexName, remoteName := splitReposSearchTerm(term) + + // Search is a long-running operation, just lock s.config to avoid block others. + s.mu.RLock() + index, err := newIndexInfo(s.config, indexName) + s.mu.RUnlock() + + if err != nil { + return nil, err + } + if index.Official { + // If pull "library/foo", it's stored locally under "foo" + remoteName = strings.TrimPrefix(remoteName, "library/") + } + + endpoint, err := newV1Endpoint(index, headers) + if err != nil { + return nil, err + } + + var client *http.Client + if authConfig != nil && authConfig.IdentityToken != "" && authConfig.Username != "" { + creds := NewStaticCredentialStore(authConfig) + scopes := []auth.Scope{ + auth.RegistryScope{ + Name: "catalog", + Actions: []string{"search"}, + }, + } + + // TODO(thaJeztah); is there a reason not to include other headers here? (originally added in 19d48f0b8ba59eea9f2cac4ad1c7977712a6b7ac) + modifiers := Headers(headers.Get("User-Agent"), nil) + v2Client, err := v2AuthHTTPClient(endpoint.URL, endpoint.client.Transport, modifiers, creds, scopes) + if err != nil { + return nil, err + } + // Copy non transport http client features + v2Client.Timeout = endpoint.client.Timeout + v2Client.CheckRedirect = endpoint.client.CheckRedirect + v2Client.Jar = endpoint.client.Jar + + logrus.Debugf("using v2 client for search to %s", endpoint.URL) + client = v2Client + } else { + client = endpoint.client + if err := authorizeClient(client, authConfig, endpoint); err != nil { + return nil, err + } + } + + return newSession(client, endpoint).searchRepositories(remoteName, limit) +} diff --git a/vendor/github.com/docker/docker/registry/service.go b/vendor/github.com/docker/docker/registry/service.go index 25b116a27..b848065b3 100644 --- a/vendor/github.com/docker/docker/registry/service.go +++ b/vendor/github.com/docker/docker/registry/service.go @@ -3,56 +3,40 @@ package registry // import "github.com/docker/docker/registry" import ( "context" "crypto/tls" - "net/http" "net/url" "strings" "sync" "github.com/docker/distribution/reference" - "github.com/docker/distribution/registry/client/auth" - "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/registry" "github.com/docker/docker/errdefs" "github.com/sirupsen/logrus" ) -// Service is the interface defining what a registry service should implement. -type Service interface { - Auth(ctx context.Context, authConfig *types.AuthConfig, userAgent string) (status, token string, err error) - LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, err error) - LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error) - ResolveRepository(name reference.Named) (*RepositoryInfo, error) - Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registry.SearchResults, error) - ServiceConfig() *registry.ServiceConfig - LoadAllowNondistributableArtifacts([]string) error - LoadMirrors([]string) error - LoadInsecureRegistries([]string) error -} - -// defaultService is a registry service. It tracks configuration data such as a list +// Service is a registry service. It tracks configuration data such as a list // of mirrors. -type defaultService struct { +type Service struct { config *serviceConfig mu sync.RWMutex } // NewService returns a new instance of defaultService ready to be // installed into an engine. -func NewService(options ServiceOptions) (Service, error) { +func NewService(options ServiceOptions) (*Service, error) { config, err := newServiceConfig(options) - return &defaultService{config: config}, err + return &Service{config: config}, err } // ServiceConfig returns a copy of the public registry service's configuration. -func (s *defaultService) ServiceConfig() *registry.ServiceConfig { +func (s *Service) ServiceConfig() *registry.ServiceConfig { s.mu.RLock() defer s.mu.RUnlock() return s.config.copy() } // LoadAllowNondistributableArtifacts loads allow-nondistributable-artifacts registries for Service. -func (s *defaultService) LoadAllowNondistributableArtifacts(registries []string) error { +func (s *Service) LoadAllowNondistributableArtifacts(registries []string) error { s.mu.Lock() defer s.mu.Unlock() @@ -60,7 +44,7 @@ func (s *defaultService) LoadAllowNondistributableArtifacts(registries []string) } // LoadMirrors loads registry mirrors for Service -func (s *defaultService) LoadMirrors(mirrors []string) error { +func (s *Service) LoadMirrors(mirrors []string) error { s.mu.Lock() defer s.mu.Unlock() @@ -68,7 +52,7 @@ func (s *defaultService) LoadMirrors(mirrors []string) error { } // LoadInsecureRegistries loads insecure registries for Service -func (s *defaultService) LoadInsecureRegistries(registries []string) error { +func (s *Service) LoadInsecureRegistries(registries []string) error { s.mu.Lock() defer s.mu.Unlock() @@ -78,7 +62,7 @@ func (s *defaultService) LoadInsecureRegistries(registries []string) error { // Auth contacts the public registry with the provided credentials, // and returns OK if authentication was successful. // It can be used to verify the validity of a client's credentials. -func (s *defaultService) Auth(ctx context.Context, authConfig *types.AuthConfig, userAgent string) (status, token string, err error) { +func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, userAgent string) (status, token string, err error) { // TODO Use ctx when searching for repositories var registryHostName = IndexHostname @@ -129,69 +113,9 @@ func splitReposSearchTerm(reposName string) (string, string) { return nameParts[0], nameParts[1] } -// Search queries the public registry for images matching the specified -// search terms, and returns the results. -func (s *defaultService) Search(ctx context.Context, term string, limit int, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registry.SearchResults, error) { - // TODO Use ctx when searching for repositories - if hasScheme(term) { - return nil, invalidParamf("invalid repository name: repository name (%s) should not have a scheme", term) - } - - indexName, remoteName := splitReposSearchTerm(term) - - // Search is a long-running operation, just lock s.config to avoid block others. - s.mu.RLock() - index, err := newIndexInfo(s.config, indexName) - s.mu.RUnlock() - - if err != nil { - return nil, err - } - if index.Official { - // If pull "library/foo", it's stored locally under "foo" - remoteName = strings.TrimPrefix(remoteName, "library/") - } - - endpoint, err := newV1Endpoint(index, userAgent, headers) - if err != nil { - return nil, err - } - - var client *http.Client - if authConfig != nil && authConfig.IdentityToken != "" && authConfig.Username != "" { - creds := NewStaticCredentialStore(authConfig) - scopes := []auth.Scope{ - auth.RegistryScope{ - Name: "catalog", - Actions: []string{"search"}, - }, - } - - modifiers := Headers(userAgent, nil) - v2Client, err := v2AuthHTTPClient(endpoint.URL, endpoint.client.Transport, modifiers, creds, scopes) - if err != nil { - return nil, err - } - // Copy non transport http client features - v2Client.Timeout = endpoint.client.Timeout - v2Client.CheckRedirect = endpoint.client.CheckRedirect - v2Client.Jar = endpoint.client.Jar - - logrus.Debugf("using v2 client for search to %s", endpoint.URL) - client = v2Client - } else { - client = endpoint.client - if err := authorizeClient(client, authConfig, endpoint); err != nil { - return nil, err - } - } - - return newSession(client, endpoint).searchRepositories(remoteName, limit) -} - // ResolveRepository splits a repository name into its components // and configuration of the associated registry. -func (s *defaultService) ResolveRepository(name reference.Named) (*RepositoryInfo, error) { +func (s *Service) ResolveRepository(name reference.Named) (*RepositoryInfo, error) { s.mu.RLock() defer s.mu.RUnlock() return newRepositoryInfo(s.config, name) @@ -210,7 +134,7 @@ type APIEndpoint struct { // LookupPullEndpoints creates a list of v2 endpoints to try to pull from, in order of preference. // It gives preference to mirrors over the actual registry, and HTTPS over plain HTTP. -func (s *defaultService) LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, err error) { +func (s *Service) LookupPullEndpoints(hostname string) (endpoints []APIEndpoint, err error) { s.mu.RLock() defer s.mu.RUnlock() @@ -219,7 +143,7 @@ func (s *defaultService) LookupPullEndpoints(hostname string) (endpoints []APIEn // LookupPushEndpoints creates a list of v2 endpoints to try to push to, in order of preference. // It gives preference to HTTPS over plain HTTP. Mirrors are not included. -func (s *defaultService) LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error) { +func (s *Service) LookupPushEndpoints(hostname string) (endpoints []APIEndpoint, err error) { s.mu.RLock() defer s.mu.RUnlock() @@ -233,3 +157,11 @@ func (s *defaultService) LookupPushEndpoints(hostname string) (endpoints []APIEn } return endpoints, err } + +// IsInsecureRegistry returns true if the registry at given host is configured as +// insecure registry. +func (s *Service) IsInsecureRegistry(host string) bool { + s.mu.RLock() + defer s.mu.RUnlock() + return !s.config.isSecureIndex(host) +} diff --git a/vendor/github.com/docker/docker/registry/service_v2.go b/vendor/github.com/docker/docker/registry/service_v2.go index d4352583f..c8c545d21 100644 --- a/vendor/github.com/docker/docker/registry/service_v2.go +++ b/vendor/github.com/docker/docker/registry/service_v2.go @@ -7,7 +7,7 @@ import ( "github.com/docker/go-connections/tlsconfig" ) -func (s *defaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, err error) { +func (s *Service) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, err error) { ana := s.config.allowNondistributableArtifacts(hostname) if hostname == DefaultNamespace || hostname == IndexHostname { diff --git a/vendor/github.com/docker/docker/registry/session.go b/vendor/github.com/docker/docker/registry/session.go index 6418e2d6b..86a5cd9ed 100644 --- a/vendor/github.com/docker/docker/registry/session.go +++ b/vendor/github.com/docker/docker/registry/session.go @@ -11,7 +11,6 @@ import ( "strings" "sync" - "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/registry" "github.com/docker/docker/errdefs" "github.com/docker/docker/pkg/ioutils" @@ -28,7 +27,7 @@ type session struct { type authTransport struct { http.RoundTripper - *types.AuthConfig + *registry.AuthConfig alwaysSetBasicAuth bool token []string @@ -50,7 +49,7 @@ type authTransport struct { // If the server sends a token without the client having requested it, it is ignored. // // This RoundTripper also has a CancelRequest method important for correct timeout handling. -func newAuthTransport(base http.RoundTripper, authConfig *types.AuthConfig, alwaysSetBasicAuth bool) *authTransport { +func newAuthTransport(base http.RoundTripper, authConfig *registry.AuthConfig, alwaysSetBasicAuth bool) *authTransport { if base == nil { base = http.DefaultTransport } @@ -145,7 +144,7 @@ func (tr *authTransport) CancelRequest(req *http.Request) { } } -func authorizeClient(client *http.Client, authConfig *types.AuthConfig, endpoint *v1Endpoint) error { +func authorizeClient(client *http.Client, authConfig *registry.AuthConfig, endpoint *v1Endpoint) error { var alwaysSetBasicAuth bool // If we're working with a standalone private registry over HTTPS, send Basic Auth headers @@ -207,10 +206,10 @@ func (r *session) searchRepositories(term string, limit int) (*registry.SearchRe } defer res.Body.Close() if res.StatusCode != http.StatusOK { - return nil, &jsonmessage.JSONError{ + return nil, errdefs.Unknown(&jsonmessage.JSONError{ Message: fmt.Sprintf("Unexpected status code %d", res.StatusCode), Code: res.StatusCode, - } + }) } result := new(registry.SearchResults) return result, errors.Wrap(json.NewDecoder(res.Body).Decode(result), "error decoding registry search results") diff --git a/vendor/github.com/dustin/go-humanize/.travis.yml b/vendor/github.com/dustin/go-humanize/.travis.yml new file mode 100644 index 000000000..ac12e485a --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/.travis.yml @@ -0,0 +1,21 @@ +sudo: false +language: go +go_import_path: github.com/dustin/go-humanize +go: + - 1.13.x + - 1.14.x + - 1.15.x + - 1.16.x + - stable + - master +matrix: + allow_failures: + - go: master + fast_finish: true +install: + - # Do nothing. This is needed to prevent default install action "go get -t -v ./..." from happening here (we want it to happen inside script step). +script: + - diff -u <(echo -n) <(gofmt -d -s .) + - go vet . + - go install -v -race ./... + - go test -v -race ./... diff --git a/vendor/github.com/dustin/go-humanize/LICENSE b/vendor/github.com/dustin/go-humanize/LICENSE new file mode 100644 index 000000000..8d9a94a90 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2005-2008 Dustin Sallings + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/vendor/github.com/dustin/go-humanize/README.markdown b/vendor/github.com/dustin/go-humanize/README.markdown new file mode 100644 index 000000000..7d0b16b34 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/README.markdown @@ -0,0 +1,124 @@ +# Humane Units [![Build Status](https://travis-ci.org/dustin/go-humanize.svg?branch=master)](https://travis-ci.org/dustin/go-humanize) [![GoDoc](https://godoc.org/github.com/dustin/go-humanize?status.svg)](https://godoc.org/github.com/dustin/go-humanize) + +Just a few functions for helping humanize times and sizes. + +`go get` it as `github.com/dustin/go-humanize`, import it as +`"github.com/dustin/go-humanize"`, use it as `humanize`. + +See [godoc](https://pkg.go.dev/github.com/dustin/go-humanize) for +complete documentation. + +## Sizes + +This lets you take numbers like `82854982` and convert them to useful +strings like, `83 MB` or `79 MiB` (whichever you prefer). + +Example: + +```go +fmt.Printf("That file is %s.", humanize.Bytes(82854982)) // That file is 83 MB. +``` + +## Times + +This lets you take a `time.Time` and spit it out in relative terms. +For example, `12 seconds ago` or `3 days from now`. + +Example: + +```go +fmt.Printf("This was touched %s.", humanize.Time(someTimeInstance)) // This was touched 7 hours ago. +``` + +Thanks to Kyle Lemons for the time implementation from an IRC +conversation one day. It's pretty neat. + +## Ordinals + +From a [mailing list discussion][odisc] where a user wanted to be able +to label ordinals. + + 0 -> 0th + 1 -> 1st + 2 -> 2nd + 3 -> 3rd + 4 -> 4th + [...] + +Example: + +```go +fmt.Printf("You're my %s best friend.", humanize.Ordinal(193)) // You are my 193rd best friend. +``` + +## Commas + +Want to shove commas into numbers? Be my guest. + + 0 -> 0 + 100 -> 100 + 1000 -> 1,000 + 1000000000 -> 1,000,000,000 + -100000 -> -100,000 + +Example: + +```go +fmt.Printf("You owe $%s.\n", humanize.Comma(6582491)) // You owe $6,582,491. +``` + +## Ftoa + +Nicer float64 formatter that removes trailing zeros. + +```go +fmt.Printf("%f", 2.24) // 2.240000 +fmt.Printf("%s", humanize.Ftoa(2.24)) // 2.24 +fmt.Printf("%f", 2.0) // 2.000000 +fmt.Printf("%s", humanize.Ftoa(2.0)) // 2 +``` + +## SI notation + +Format numbers with [SI notation][sinotation]. + +Example: + +```go +humanize.SI(0.00000000223, "M") // 2.23 nM +``` + +## English-specific functions + +The following functions are in the `humanize/english` subpackage. + +### Plurals + +Simple English pluralization + +```go +english.PluralWord(1, "object", "") // object +english.PluralWord(42, "object", "") // objects +english.PluralWord(2, "bus", "") // buses +english.PluralWord(99, "locus", "loci") // loci + +english.Plural(1, "object", "") // 1 object +english.Plural(42, "object", "") // 42 objects +english.Plural(2, "bus", "") // 2 buses +english.Plural(99, "locus", "loci") // 99 loci +``` + +### Word series + +Format comma-separated words lists with conjuctions: + +```go +english.WordSeries([]string{"foo"}, "and") // foo +english.WordSeries([]string{"foo", "bar"}, "and") // foo and bar +english.WordSeries([]string{"foo", "bar", "baz"}, "and") // foo, bar and baz + +english.OxfordWordSeries([]string{"foo", "bar", "baz"}, "and") // foo, bar, and baz +``` + +[odisc]: https://groups.google.com/d/topic/golang-nuts/l8NhI74jl-4/discussion +[sinotation]: http://en.wikipedia.org/wiki/Metric_prefix diff --git a/vendor/github.com/dustin/go-humanize/big.go b/vendor/github.com/dustin/go-humanize/big.go new file mode 100644 index 000000000..f49dc337d --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/big.go @@ -0,0 +1,31 @@ +package humanize + +import ( + "math/big" +) + +// order of magnitude (to a max order) +func oomm(n, b *big.Int, maxmag int) (float64, int) { + mag := 0 + m := &big.Int{} + for n.Cmp(b) >= 0 { + n.DivMod(n, b, m) + mag++ + if mag == maxmag && maxmag >= 0 { + break + } + } + return float64(n.Int64()) + (float64(m.Int64()) / float64(b.Int64())), mag +} + +// total order of magnitude +// (same as above, but with no upper limit) +func oom(n, b *big.Int) (float64, int) { + mag := 0 + m := &big.Int{} + for n.Cmp(b) >= 0 { + n.DivMod(n, b, m) + mag++ + } + return float64(n.Int64()) + (float64(m.Int64()) / float64(b.Int64())), mag +} diff --git a/vendor/github.com/dustin/go-humanize/bigbytes.go b/vendor/github.com/dustin/go-humanize/bigbytes.go new file mode 100644 index 000000000..3b015fd59 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/bigbytes.go @@ -0,0 +1,189 @@ +package humanize + +import ( + "fmt" + "math/big" + "strings" + "unicode" +) + +var ( + bigIECExp = big.NewInt(1024) + + // BigByte is one byte in bit.Ints + BigByte = big.NewInt(1) + // BigKiByte is 1,024 bytes in bit.Ints + BigKiByte = (&big.Int{}).Mul(BigByte, bigIECExp) + // BigMiByte is 1,024 k bytes in bit.Ints + BigMiByte = (&big.Int{}).Mul(BigKiByte, bigIECExp) + // BigGiByte is 1,024 m bytes in bit.Ints + BigGiByte = (&big.Int{}).Mul(BigMiByte, bigIECExp) + // BigTiByte is 1,024 g bytes in bit.Ints + BigTiByte = (&big.Int{}).Mul(BigGiByte, bigIECExp) + // BigPiByte is 1,024 t bytes in bit.Ints + BigPiByte = (&big.Int{}).Mul(BigTiByte, bigIECExp) + // BigEiByte is 1,024 p bytes in bit.Ints + BigEiByte = (&big.Int{}).Mul(BigPiByte, bigIECExp) + // BigZiByte is 1,024 e bytes in bit.Ints + BigZiByte = (&big.Int{}).Mul(BigEiByte, bigIECExp) + // BigYiByte is 1,024 z bytes in bit.Ints + BigYiByte = (&big.Int{}).Mul(BigZiByte, bigIECExp) + // BigRiByte is 1,024 y bytes in bit.Ints + BigRiByte = (&big.Int{}).Mul(BigYiByte, bigIECExp) + // BigQiByte is 1,024 r bytes in bit.Ints + BigQiByte = (&big.Int{}).Mul(BigRiByte, bigIECExp) +) + +var ( + bigSIExp = big.NewInt(1000) + + // BigSIByte is one SI byte in big.Ints + BigSIByte = big.NewInt(1) + // BigKByte is 1,000 SI bytes in big.Ints + BigKByte = (&big.Int{}).Mul(BigSIByte, bigSIExp) + // BigMByte is 1,000 SI k bytes in big.Ints + BigMByte = (&big.Int{}).Mul(BigKByte, bigSIExp) + // BigGByte is 1,000 SI m bytes in big.Ints + BigGByte = (&big.Int{}).Mul(BigMByte, bigSIExp) + // BigTByte is 1,000 SI g bytes in big.Ints + BigTByte = (&big.Int{}).Mul(BigGByte, bigSIExp) + // BigPByte is 1,000 SI t bytes in big.Ints + BigPByte = (&big.Int{}).Mul(BigTByte, bigSIExp) + // BigEByte is 1,000 SI p bytes in big.Ints + BigEByte = (&big.Int{}).Mul(BigPByte, bigSIExp) + // BigZByte is 1,000 SI e bytes in big.Ints + BigZByte = (&big.Int{}).Mul(BigEByte, bigSIExp) + // BigYByte is 1,000 SI z bytes in big.Ints + BigYByte = (&big.Int{}).Mul(BigZByte, bigSIExp) + // BigRByte is 1,000 SI y bytes in big.Ints + BigRByte = (&big.Int{}).Mul(BigYByte, bigSIExp) + // BigQByte is 1,000 SI r bytes in big.Ints + BigQByte = (&big.Int{}).Mul(BigRByte, bigSIExp) +) + +var bigBytesSizeTable = map[string]*big.Int{ + "b": BigByte, + "kib": BigKiByte, + "kb": BigKByte, + "mib": BigMiByte, + "mb": BigMByte, + "gib": BigGiByte, + "gb": BigGByte, + "tib": BigTiByte, + "tb": BigTByte, + "pib": BigPiByte, + "pb": BigPByte, + "eib": BigEiByte, + "eb": BigEByte, + "zib": BigZiByte, + "zb": BigZByte, + "yib": BigYiByte, + "yb": BigYByte, + "rib": BigRiByte, + "rb": BigRByte, + "qib": BigQiByte, + "qb": BigQByte, + // Without suffix + "": BigByte, + "ki": BigKiByte, + "k": BigKByte, + "mi": BigMiByte, + "m": BigMByte, + "gi": BigGiByte, + "g": BigGByte, + "ti": BigTiByte, + "t": BigTByte, + "pi": BigPiByte, + "p": BigPByte, + "ei": BigEiByte, + "e": BigEByte, + "z": BigZByte, + "zi": BigZiByte, + "y": BigYByte, + "yi": BigYiByte, + "r": BigRByte, + "ri": BigRiByte, + "q": BigQByte, + "qi": BigQiByte, +} + +var ten = big.NewInt(10) + +func humanateBigBytes(s, base *big.Int, sizes []string) string { + if s.Cmp(ten) < 0 { + return fmt.Sprintf("%d B", s) + } + c := (&big.Int{}).Set(s) + val, mag := oomm(c, base, len(sizes)-1) + suffix := sizes[mag] + f := "%.0f %s" + if val < 10 { + f = "%.1f %s" + } + + return fmt.Sprintf(f, val, suffix) + +} + +// BigBytes produces a human readable representation of an SI size. +// +// See also: ParseBigBytes. +// +// BigBytes(82854982) -> 83 MB +func BigBytes(s *big.Int) string { + sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", "RB", "QB"} + return humanateBigBytes(s, bigSIExp, sizes) +} + +// BigIBytes produces a human readable representation of an IEC size. +// +// See also: ParseBigBytes. +// +// BigIBytes(82854982) -> 79 MiB +func BigIBytes(s *big.Int) string { + sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", "RiB", "QiB"} + return humanateBigBytes(s, bigIECExp, sizes) +} + +// ParseBigBytes parses a string representation of bytes into the number +// of bytes it represents. +// +// See also: BigBytes, BigIBytes. +// +// ParseBigBytes("42 MB") -> 42000000, nil +// ParseBigBytes("42 mib") -> 44040192, nil +func ParseBigBytes(s string) (*big.Int, error) { + lastDigit := 0 + hasComma := false + for _, r := range s { + if !(unicode.IsDigit(r) || r == '.' || r == ',') { + break + } + if r == ',' { + hasComma = true + } + lastDigit++ + } + + num := s[:lastDigit] + if hasComma { + num = strings.Replace(num, ",", "", -1) + } + + val := &big.Rat{} + _, err := fmt.Sscanf(num, "%f", val) + if err != nil { + return nil, err + } + + extra := strings.ToLower(strings.TrimSpace(s[lastDigit:])) + if m, ok := bigBytesSizeTable[extra]; ok { + mv := (&big.Rat{}).SetInt(m) + val.Mul(val, mv) + rv := &big.Int{} + rv.Div(val.Num(), val.Denom()) + return rv, nil + } + + return nil, fmt.Errorf("unhandled size name: %v", extra) +} diff --git a/vendor/github.com/dustin/go-humanize/bytes.go b/vendor/github.com/dustin/go-humanize/bytes.go new file mode 100644 index 000000000..0b498f488 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/bytes.go @@ -0,0 +1,143 @@ +package humanize + +import ( + "fmt" + "math" + "strconv" + "strings" + "unicode" +) + +// IEC Sizes. +// kibis of bits +const ( + Byte = 1 << (iota * 10) + KiByte + MiByte + GiByte + TiByte + PiByte + EiByte +) + +// SI Sizes. +const ( + IByte = 1 + KByte = IByte * 1000 + MByte = KByte * 1000 + GByte = MByte * 1000 + TByte = GByte * 1000 + PByte = TByte * 1000 + EByte = PByte * 1000 +) + +var bytesSizeTable = map[string]uint64{ + "b": Byte, + "kib": KiByte, + "kb": KByte, + "mib": MiByte, + "mb": MByte, + "gib": GiByte, + "gb": GByte, + "tib": TiByte, + "tb": TByte, + "pib": PiByte, + "pb": PByte, + "eib": EiByte, + "eb": EByte, + // Without suffix + "": Byte, + "ki": KiByte, + "k": KByte, + "mi": MiByte, + "m": MByte, + "gi": GiByte, + "g": GByte, + "ti": TiByte, + "t": TByte, + "pi": PiByte, + "p": PByte, + "ei": EiByte, + "e": EByte, +} + +func logn(n, b float64) float64 { + return math.Log(n) / math.Log(b) +} + +func humanateBytes(s uint64, base float64, sizes []string) string { + if s < 10 { + return fmt.Sprintf("%d B", s) + } + e := math.Floor(logn(float64(s), base)) + suffix := sizes[int(e)] + val := math.Floor(float64(s)/math.Pow(base, e)*10+0.5) / 10 + f := "%.0f %s" + if val < 10 { + f = "%.1f %s" + } + + return fmt.Sprintf(f, val, suffix) +} + +// Bytes produces a human readable representation of an SI size. +// +// See also: ParseBytes. +// +// Bytes(82854982) -> 83 MB +func Bytes(s uint64) string { + sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB"} + return humanateBytes(s, 1000, sizes) +} + +// IBytes produces a human readable representation of an IEC size. +// +// See also: ParseBytes. +// +// IBytes(82854982) -> 79 MiB +func IBytes(s uint64) string { + sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"} + return humanateBytes(s, 1024, sizes) +} + +// ParseBytes parses a string representation of bytes into the number +// of bytes it represents. +// +// See Also: Bytes, IBytes. +// +// ParseBytes("42 MB") -> 42000000, nil +// ParseBytes("42 mib") -> 44040192, nil +func ParseBytes(s string) (uint64, error) { + lastDigit := 0 + hasComma := false + for _, r := range s { + if !(unicode.IsDigit(r) || r == '.' || r == ',') { + break + } + if r == ',' { + hasComma = true + } + lastDigit++ + } + + num := s[:lastDigit] + if hasComma { + num = strings.Replace(num, ",", "", -1) + } + + f, err := strconv.ParseFloat(num, 64) + if err != nil { + return 0, err + } + + extra := strings.ToLower(strings.TrimSpace(s[lastDigit:])) + if m, ok := bytesSizeTable[extra]; ok { + f *= float64(m) + if f >= math.MaxUint64 { + return 0, fmt.Errorf("too large: %v", s) + } + return uint64(f), nil + } + + return 0, fmt.Errorf("unhandled size name: %v", extra) +} diff --git a/vendor/github.com/dustin/go-humanize/comma.go b/vendor/github.com/dustin/go-humanize/comma.go new file mode 100644 index 000000000..520ae3e57 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/comma.go @@ -0,0 +1,116 @@ +package humanize + +import ( + "bytes" + "math" + "math/big" + "strconv" + "strings" +) + +// Comma produces a string form of the given number in base 10 with +// commas after every three orders of magnitude. +// +// e.g. Comma(834142) -> 834,142 +func Comma(v int64) string { + sign := "" + + // Min int64 can't be negated to a usable value, so it has to be special cased. + if v == math.MinInt64 { + return "-9,223,372,036,854,775,808" + } + + if v < 0 { + sign = "-" + v = 0 - v + } + + parts := []string{"", "", "", "", "", "", ""} + j := len(parts) - 1 + + for v > 999 { + parts[j] = strconv.FormatInt(v%1000, 10) + switch len(parts[j]) { + case 2: + parts[j] = "0" + parts[j] + case 1: + parts[j] = "00" + parts[j] + } + v = v / 1000 + j-- + } + parts[j] = strconv.Itoa(int(v)) + return sign + strings.Join(parts[j:], ",") +} + +// Commaf produces a string form of the given number in base 10 with +// commas after every three orders of magnitude. +// +// e.g. Commaf(834142.32) -> 834,142.32 +func Commaf(v float64) string { + buf := &bytes.Buffer{} + if v < 0 { + buf.Write([]byte{'-'}) + v = 0 - v + } + + comma := []byte{','} + + parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".") + pos := 0 + if len(parts[0])%3 != 0 { + pos += len(parts[0]) % 3 + buf.WriteString(parts[0][:pos]) + buf.Write(comma) + } + for ; pos < len(parts[0]); pos += 3 { + buf.WriteString(parts[0][pos : pos+3]) + buf.Write(comma) + } + buf.Truncate(buf.Len() - 1) + + if len(parts) > 1 { + buf.Write([]byte{'.'}) + buf.WriteString(parts[1]) + } + return buf.String() +} + +// CommafWithDigits works like the Commaf but limits the resulting +// string to the given number of decimal places. +// +// e.g. CommafWithDigits(834142.32, 1) -> 834,142.3 +func CommafWithDigits(f float64, decimals int) string { + return stripTrailingDigits(Commaf(f), decimals) +} + +// BigComma produces a string form of the given big.Int in base 10 +// with commas after every three orders of magnitude. +func BigComma(b *big.Int) string { + sign := "" + if b.Sign() < 0 { + sign = "-" + b.Abs(b) + } + + athousand := big.NewInt(1000) + c := (&big.Int{}).Set(b) + _, m := oom(c, athousand) + parts := make([]string, m+1) + j := len(parts) - 1 + + mod := &big.Int{} + for b.Cmp(athousand) >= 0 { + b.DivMod(b, athousand, mod) + parts[j] = strconv.FormatInt(mod.Int64(), 10) + switch len(parts[j]) { + case 2: + parts[j] = "0" + parts[j] + case 1: + parts[j] = "00" + parts[j] + } + j-- + } + parts[j] = strconv.Itoa(int(b.Int64())) + return sign + strings.Join(parts[j:], ",") +} diff --git a/vendor/github.com/dustin/go-humanize/commaf.go b/vendor/github.com/dustin/go-humanize/commaf.go new file mode 100644 index 000000000..2bc83a03c --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/commaf.go @@ -0,0 +1,41 @@ +//go:build go1.6 +// +build go1.6 + +package humanize + +import ( + "bytes" + "math/big" + "strings" +) + +// BigCommaf produces a string form of the given big.Float in base 10 +// with commas after every three orders of magnitude. +func BigCommaf(v *big.Float) string { + buf := &bytes.Buffer{} + if v.Sign() < 0 { + buf.Write([]byte{'-'}) + v.Abs(v) + } + + comma := []byte{','} + + parts := strings.Split(v.Text('f', -1), ".") + pos := 0 + if len(parts[0])%3 != 0 { + pos += len(parts[0]) % 3 + buf.WriteString(parts[0][:pos]) + buf.Write(comma) + } + for ; pos < len(parts[0]); pos += 3 { + buf.WriteString(parts[0][pos : pos+3]) + buf.Write(comma) + } + buf.Truncate(buf.Len() - 1) + + if len(parts) > 1 { + buf.Write([]byte{'.'}) + buf.WriteString(parts[1]) + } + return buf.String() +} diff --git a/vendor/github.com/dustin/go-humanize/ftoa.go b/vendor/github.com/dustin/go-humanize/ftoa.go new file mode 100644 index 000000000..bce923f37 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/ftoa.go @@ -0,0 +1,49 @@ +package humanize + +import ( + "strconv" + "strings" +) + +func stripTrailingZeros(s string) string { + if !strings.ContainsRune(s, '.') { + return s + } + offset := len(s) - 1 + for offset > 0 { + if s[offset] == '.' { + offset-- + break + } + if s[offset] != '0' { + break + } + offset-- + } + return s[:offset+1] +} + +func stripTrailingDigits(s string, digits int) string { + if i := strings.Index(s, "."); i >= 0 { + if digits <= 0 { + return s[:i] + } + i++ + if i+digits >= len(s) { + return s + } + return s[:i+digits] + } + return s +} + +// Ftoa converts a float to a string with no trailing zeros. +func Ftoa(num float64) string { + return stripTrailingZeros(strconv.FormatFloat(num, 'f', 6, 64)) +} + +// FtoaWithDigits converts a float to a string but limits the resulting string +// to the given number of decimal places, and no trailing zeros. +func FtoaWithDigits(num float64, digits int) string { + return stripTrailingZeros(stripTrailingDigits(strconv.FormatFloat(num, 'f', 6, 64), digits)) +} diff --git a/vendor/github.com/dustin/go-humanize/humanize.go b/vendor/github.com/dustin/go-humanize/humanize.go new file mode 100644 index 000000000..a2c2da31e --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/humanize.go @@ -0,0 +1,8 @@ +/* +Package humanize converts boring ugly numbers to human-friendly strings and back. + +Durations can be turned into strings such as "3 days ago", numbers +representing sizes like 82854982 into useful strings like, "83 MB" or +"79 MiB" (whichever you prefer). +*/ +package humanize diff --git a/vendor/github.com/dustin/go-humanize/number.go b/vendor/github.com/dustin/go-humanize/number.go new file mode 100644 index 000000000..6470d0d47 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/number.go @@ -0,0 +1,192 @@ +package humanize + +/* +Slightly adapted from the source to fit go-humanize. + +Author: https://github.com/gorhill +Source: https://gist.github.com/gorhill/5285193 + +*/ + +import ( + "math" + "strconv" +) + +var ( + renderFloatPrecisionMultipliers = [...]float64{ + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + } + + renderFloatPrecisionRounders = [...]float64{ + 0.5, + 0.05, + 0.005, + 0.0005, + 0.00005, + 0.000005, + 0.0000005, + 0.00000005, + 0.000000005, + 0.0000000005, + } +) + +// FormatFloat produces a formatted number as string based on the following user-specified criteria: +// * thousands separator +// * decimal separator +// * decimal precision +// +// Usage: s := RenderFloat(format, n) +// The format parameter tells how to render the number n. +// +// See examples: http://play.golang.org/p/LXc1Ddm1lJ +// +// Examples of format strings, given n = 12345.6789: +// "#,###.##" => "12,345.67" +// "#,###." => "12,345" +// "#,###" => "12345,678" +// "#\u202F###,##" => "12 345,68" +// "#.###,###### => 12.345,678900 +// "" (aka default format) => 12,345.67 +// +// The highest precision allowed is 9 digits after the decimal symbol. +// There is also a version for integer number, FormatInteger(), +// which is convenient for calls within template. +func FormatFloat(format string, n float64) string { + // Special cases: + // NaN = "NaN" + // +Inf = "+Infinity" + // -Inf = "-Infinity" + if math.IsNaN(n) { + return "NaN" + } + if n > math.MaxFloat64 { + return "Infinity" + } + if n < (0.0 - math.MaxFloat64) { + return "-Infinity" + } + + // default format + precision := 2 + decimalStr := "." + thousandStr := "," + positiveStr := "" + negativeStr := "-" + + if len(format) > 0 { + format := []rune(format) + + // If there is an explicit format directive, + // then default values are these: + precision = 9 + thousandStr = "" + + // collect indices of meaningful formatting directives + formatIndx := []int{} + for i, char := range format { + if char != '#' && char != '0' { + formatIndx = append(formatIndx, i) + } + } + + if len(formatIndx) > 0 { + // Directive at index 0: + // Must be a '+' + // Raise an error if not the case + // index: 0123456789 + // +0.000,000 + // +000,000.0 + // +0000.00 + // +0000 + if formatIndx[0] == 0 { + if format[formatIndx[0]] != '+' { + panic("RenderFloat(): invalid positive sign directive") + } + positiveStr = "+" + formatIndx = formatIndx[1:] + } + + // Two directives: + // First is thousands separator + // Raise an error if not followed by 3-digit + // 0123456789 + // 0.000,000 + // 000,000.00 + if len(formatIndx) == 2 { + if (formatIndx[1] - formatIndx[0]) != 4 { + panic("RenderFloat(): thousands separator directive must be followed by 3 digit-specifiers") + } + thousandStr = string(format[formatIndx[0]]) + formatIndx = formatIndx[1:] + } + + // One directive: + // Directive is decimal separator + // The number of digit-specifier following the separator indicates wanted precision + // 0123456789 + // 0.00 + // 000,0000 + if len(formatIndx) == 1 { + decimalStr = string(format[formatIndx[0]]) + precision = len(format) - formatIndx[0] - 1 + } + } + } + + // generate sign part + var signStr string + if n >= 0.000000001 { + signStr = positiveStr + } else if n <= -0.000000001 { + signStr = negativeStr + n = -n + } else { + signStr = "" + n = 0.0 + } + + // split number into integer and fractional parts + intf, fracf := math.Modf(n + renderFloatPrecisionRounders[precision]) + + // generate integer part string + intStr := strconv.FormatInt(int64(intf), 10) + + // add thousand separator if required + if len(thousandStr) > 0 { + for i := len(intStr); i > 3; { + i -= 3 + intStr = intStr[:i] + thousandStr + intStr[i:] + } + } + + // no fractional part, we can leave now + if precision == 0 { + return signStr + intStr + } + + // generate fractional part + fracStr := strconv.Itoa(int(fracf * renderFloatPrecisionMultipliers[precision])) + // may need padding + if len(fracStr) < precision { + fracStr = "000000000000000"[:precision-len(fracStr)] + fracStr + } + + return signStr + intStr + decimalStr + fracStr +} + +// FormatInteger produces a formatted number as string. +// See FormatFloat. +func FormatInteger(format string, n int) string { + return FormatFloat(format, float64(n)) +} diff --git a/vendor/github.com/dustin/go-humanize/ordinals.go b/vendor/github.com/dustin/go-humanize/ordinals.go new file mode 100644 index 000000000..43d88a861 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/ordinals.go @@ -0,0 +1,25 @@ +package humanize + +import "strconv" + +// Ordinal gives you the input number in a rank/ordinal format. +// +// Ordinal(3) -> 3rd +func Ordinal(x int) string { + suffix := "th" + switch x % 10 { + case 1: + if x%100 != 11 { + suffix = "st" + } + case 2: + if x%100 != 12 { + suffix = "nd" + } + case 3: + if x%100 != 13 { + suffix = "rd" + } + } + return strconv.Itoa(x) + suffix +} diff --git a/vendor/github.com/dustin/go-humanize/si.go b/vendor/github.com/dustin/go-humanize/si.go new file mode 100644 index 000000000..8b8501984 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/si.go @@ -0,0 +1,127 @@ +package humanize + +import ( + "errors" + "math" + "regexp" + "strconv" +) + +var siPrefixTable = map[float64]string{ + -30: "q", // quecto + -27: "r", // ronto + -24: "y", // yocto + -21: "z", // zepto + -18: "a", // atto + -15: "f", // femto + -12: "p", // pico + -9: "n", // nano + -6: "µ", // micro + -3: "m", // milli + 0: "", + 3: "k", // kilo + 6: "M", // mega + 9: "G", // giga + 12: "T", // tera + 15: "P", // peta + 18: "E", // exa + 21: "Z", // zetta + 24: "Y", // yotta + 27: "R", // ronna + 30: "Q", // quetta +} + +var revSIPrefixTable = revfmap(siPrefixTable) + +// revfmap reverses the map and precomputes the power multiplier +func revfmap(in map[float64]string) map[string]float64 { + rv := map[string]float64{} + for k, v := range in { + rv[v] = math.Pow(10, k) + } + return rv +} + +var riParseRegex *regexp.Regexp + +func init() { + ri := `^([\-0-9.]+)\s?([` + for _, v := range siPrefixTable { + ri += v + } + ri += `]?)(.*)` + + riParseRegex = regexp.MustCompile(ri) +} + +// ComputeSI finds the most appropriate SI prefix for the given number +// and returns the prefix along with the value adjusted to be within +// that prefix. +// +// See also: SI, ParseSI. +// +// e.g. ComputeSI(2.2345e-12) -> (2.2345, "p") +func ComputeSI(input float64) (float64, string) { + if input == 0 { + return 0, "" + } + mag := math.Abs(input) + exponent := math.Floor(logn(mag, 10)) + exponent = math.Floor(exponent/3) * 3 + + value := mag / math.Pow(10, exponent) + + // Handle special case where value is exactly 1000.0 + // Should return 1 M instead of 1000 k + if value == 1000.0 { + exponent += 3 + value = mag / math.Pow(10, exponent) + } + + value = math.Copysign(value, input) + + prefix := siPrefixTable[exponent] + return value, prefix +} + +// SI returns a string with default formatting. +// +// SI uses Ftoa to format float value, removing trailing zeros. +// +// See also: ComputeSI, ParseSI. +// +// e.g. SI(1000000, "B") -> 1 MB +// e.g. SI(2.2345e-12, "F") -> 2.2345 pF +func SI(input float64, unit string) string { + value, prefix := ComputeSI(input) + return Ftoa(value) + " " + prefix + unit +} + +// SIWithDigits works like SI but limits the resulting string to the +// given number of decimal places. +// +// e.g. SIWithDigits(1000000, 0, "B") -> 1 MB +// e.g. SIWithDigits(2.2345e-12, 2, "F") -> 2.23 pF +func SIWithDigits(input float64, decimals int, unit string) string { + value, prefix := ComputeSI(input) + return FtoaWithDigits(value, decimals) + " " + prefix + unit +} + +var errInvalid = errors.New("invalid input") + +// ParseSI parses an SI string back into the number and unit. +// +// See also: SI, ComputeSI. +// +// e.g. ParseSI("2.2345 pF") -> (2.2345e-12, "F", nil) +func ParseSI(input string) (float64, string, error) { + found := riParseRegex.FindStringSubmatch(input) + if len(found) != 4 { + return 0, "", errInvalid + } + mag := revSIPrefixTable[found[2]] + unit := found[3] + + base, err := strconv.ParseFloat(found[1], 64) + return base * mag, unit, err +} diff --git a/vendor/github.com/dustin/go-humanize/times.go b/vendor/github.com/dustin/go-humanize/times.go new file mode 100644 index 000000000..dd3fbf5ef --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/times.go @@ -0,0 +1,117 @@ +package humanize + +import ( + "fmt" + "math" + "sort" + "time" +) + +// Seconds-based time units +const ( + Day = 24 * time.Hour + Week = 7 * Day + Month = 30 * Day + Year = 12 * Month + LongTime = 37 * Year +) + +// Time formats a time into a relative string. +// +// Time(someT) -> "3 weeks ago" +func Time(then time.Time) string { + return RelTime(then, time.Now(), "ago", "from now") +} + +// A RelTimeMagnitude struct contains a relative time point at which +// the relative format of time will switch to a new format string. A +// slice of these in ascending order by their "D" field is passed to +// CustomRelTime to format durations. +// +// The Format field is a string that may contain a "%s" which will be +// replaced with the appropriate signed label (e.g. "ago" or "from +// now") and a "%d" that will be replaced by the quantity. +// +// The DivBy field is the amount of time the time difference must be +// divided by in order to display correctly. +// +// e.g. if D is 2*time.Minute and you want to display "%d minutes %s" +// DivBy should be time.Minute so whatever the duration is will be +// expressed in minutes. +type RelTimeMagnitude struct { + D time.Duration + Format string + DivBy time.Duration +} + +var defaultMagnitudes = []RelTimeMagnitude{ + {time.Second, "now", time.Second}, + {2 * time.Second, "1 second %s", 1}, + {time.Minute, "%d seconds %s", time.Second}, + {2 * time.Minute, "1 minute %s", 1}, + {time.Hour, "%d minutes %s", time.Minute}, + {2 * time.Hour, "1 hour %s", 1}, + {Day, "%d hours %s", time.Hour}, + {2 * Day, "1 day %s", 1}, + {Week, "%d days %s", Day}, + {2 * Week, "1 week %s", 1}, + {Month, "%d weeks %s", Week}, + {2 * Month, "1 month %s", 1}, + {Year, "%d months %s", Month}, + {18 * Month, "1 year %s", 1}, + {2 * Year, "2 years %s", 1}, + {LongTime, "%d years %s", Year}, + {math.MaxInt64, "a long while %s", 1}, +} + +// RelTime formats a time into a relative string. +// +// It takes two times and two labels. In addition to the generic time +// delta string (e.g. 5 minutes), the labels are used applied so that +// the label corresponding to the smaller time is applied. +// +// RelTime(timeInPast, timeInFuture, "earlier", "later") -> "3 weeks earlier" +func RelTime(a, b time.Time, albl, blbl string) string { + return CustomRelTime(a, b, albl, blbl, defaultMagnitudes) +} + +// CustomRelTime formats a time into a relative string. +// +// It takes two times two labels and a table of relative time formats. +// In addition to the generic time delta string (e.g. 5 minutes), the +// labels are used applied so that the label corresponding to the +// smaller time is applied. +func CustomRelTime(a, b time.Time, albl, blbl string, magnitudes []RelTimeMagnitude) string { + lbl := albl + diff := b.Sub(a) + + if a.After(b) { + lbl = blbl + diff = a.Sub(b) + } + + n := sort.Search(len(magnitudes), func(i int) bool { + return magnitudes[i].D > diff + }) + + if n >= len(magnitudes) { + n = len(magnitudes) - 1 + } + mag := magnitudes[n] + args := []interface{}{} + escaped := false + for _, ch := range mag.Format { + if escaped { + switch ch { + case 's': + args = append(args, lbl) + case 'd': + args = append(args, diff/mag.DivBy) + } + escaped = false + } else { + escaped = ch == '%' + } + } + return fmt.Sprintf(mag.Format, args...) +} diff --git a/vendor/github.com/ebitengine/purego/.gitignore b/vendor/github.com/ebitengine/purego/.gitignore new file mode 100644 index 000000000..b25c15b81 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE b/vendor/github.com/ebitengine/purego/LICENSE similarity index 100% rename from vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE rename to vendor/github.com/ebitengine/purego/LICENSE diff --git a/vendor/github.com/ebitengine/purego/README.md b/vendor/github.com/ebitengine/purego/README.md new file mode 100644 index 000000000..7115f7276 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/README.md @@ -0,0 +1,74 @@ +# purego +[![Go Reference](https://pkg.go.dev/badge/github.com/ebitengine/purego?GOOS=darwin.svg)](https://pkg.go.dev/github.com/ebitengine/purego?GOOS=darwin) + +A library for calling C functions from Go without Cgo. + +## Motivation + +The [Ebitengine](https://github.com/hajimehoshi/ebiten) game engine was ported to use only Go on Windows. This enabled +cross-compiling to Windows from any other operating system simply by setting `GOOS=windows`. The purego project was +born to bring that same vision to the other platforms supported by Ebitengine. + +## Benefits + +- **Simple Cross-Compilation**: No C means you can build for other platforms easily without a C compiler. +- **Faster Compilation**: Efficiently cache your entirely Go builds. +- **Smaller Binaries**: Using Cgo generates a C wrapper function for each C function called. Purego doesn't! +- **Dynamic Linking**: Load symbols at runtime and use it as a plugin system. +- **Foreign Function Interface**: Call into other languages that are compiled into shared objects. + +## Example + +This example only works on macOS and Linux. For a complete example look at [libc](https://github.com/ebitengine/purego/tree/main/examples/libc) which supports Windows and FreeBSD. + +```go +package main + +import ( + "fmt" + "runtime" + + "github.com/ebitengine/purego" +) + +func getSystemLibrary() string { + switch runtime.GOOS { + case "darwin": + return "/usr/lib/libSystem.B.dylib" + case "linux": + return "libc.so.6" + default: + panic(fmt.Errorf("GOOS=%s is not supported", runtime.GOOS)) + } +} + +func main() { + libc, err := purego.Dlopen(getSystemLibrary(), purego.RTLD_NOW|purego.RTLD_GLOBAL) + if err != nil { + panic(err) + } + var puts func(string) + purego.RegisterLibFunc(&puts, libc, "puts") + puts("Calling C from Go without Cgo!") +} +``` + +Then to run: `CGO_ENABLED=0 go run main.go` + +### External Code + +Purego uses code that originates from the Go runtime. These files are under the BSD-3 +License that can be found [in the Go Source](https://github.com/golang/go/blob/master/LICENSE). +This is a list of the copied files: + +* `abi_*.h` from package `runtime/cgo` +* `zcallback_darwin_*.s` from package `runtime` +* `internal/fakecgo/abi_*.h` from package `runtime/cgo` +* `internal/fakecgo/asm_GOARCH.s` from package `runtime/cgo` +* `internal/fakecgo/callbacks.go` from package `runtime/cgo` +* `internal/fakecgo/go_GOOS_GOARCH.go` from package `runtime/cgo` +* `internal/fakecgo/iscgo.go` from package `runtime/cgo` +* `internal/fakecgo/setenv.go` from package `runtime/cgo` +* `internal/fakecgo/freebsd.go` from package `runtime/cgo` + +The files `abi_*.h` and `internal/fakecgo/abi_*.h` are the same because Bazel does not support cross-package use of `#include` so we need each one once per package. (cf. [issue](https://github.com/bazelbuild/rules_go/issues/3636)) diff --git a/vendor/github.com/ebitengine/purego/abi_amd64.h b/vendor/github.com/ebitengine/purego/abi_amd64.h new file mode 100644 index 000000000..9949435fe --- /dev/null +++ b/vendor/github.com/ebitengine/purego/abi_amd64.h @@ -0,0 +1,99 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Macros for transitioning from the host ABI to Go ABI0. +// +// These save the frame pointer, so in general, functions that use +// these should have zero frame size to suppress the automatic frame +// pointer, though it's harmless to not do this. + +#ifdef GOOS_windows + +// REGS_HOST_TO_ABI0_STACK is the stack bytes used by +// PUSH_REGS_HOST_TO_ABI0. +#define REGS_HOST_TO_ABI0_STACK (28*8 + 8) + +// PUSH_REGS_HOST_TO_ABI0 prepares for transitioning from +// the host ABI to Go ABI0 code. It saves all registers that are +// callee-save in the host ABI and caller-save in Go ABI0 and prepares +// for entry to Go. +// +// Save DI SI BP BX R12 R13 R14 R15 X6-X15 registers and the DF flag. +// Clear the DF flag for the Go ABI. +// MXCSR matches the Go ABI, so we don't have to set that, +// and Go doesn't modify it, so we don't have to save it. +#define PUSH_REGS_HOST_TO_ABI0() \ + PUSHFQ \ + CLD \ + ADJSP $(REGS_HOST_TO_ABI0_STACK - 8) \ + MOVQ DI, (0*0)(SP) \ + MOVQ SI, (1*8)(SP) \ + MOVQ BP, (2*8)(SP) \ + MOVQ BX, (3*8)(SP) \ + MOVQ R12, (4*8)(SP) \ + MOVQ R13, (5*8)(SP) \ + MOVQ R14, (6*8)(SP) \ + MOVQ R15, (7*8)(SP) \ + MOVUPS X6, (8*8)(SP) \ + MOVUPS X7, (10*8)(SP) \ + MOVUPS X8, (12*8)(SP) \ + MOVUPS X9, (14*8)(SP) \ + MOVUPS X10, (16*8)(SP) \ + MOVUPS X11, (18*8)(SP) \ + MOVUPS X12, (20*8)(SP) \ + MOVUPS X13, (22*8)(SP) \ + MOVUPS X14, (24*8)(SP) \ + MOVUPS X15, (26*8)(SP) + +#define POP_REGS_HOST_TO_ABI0() \ + MOVQ (0*0)(SP), DI \ + MOVQ (1*8)(SP), SI \ + MOVQ (2*8)(SP), BP \ + MOVQ (3*8)(SP), BX \ + MOVQ (4*8)(SP), R12 \ + MOVQ (5*8)(SP), R13 \ + MOVQ (6*8)(SP), R14 \ + MOVQ (7*8)(SP), R15 \ + MOVUPS (8*8)(SP), X6 \ + MOVUPS (10*8)(SP), X7 \ + MOVUPS (12*8)(SP), X8 \ + MOVUPS (14*8)(SP), X9 \ + MOVUPS (16*8)(SP), X10 \ + MOVUPS (18*8)(SP), X11 \ + MOVUPS (20*8)(SP), X12 \ + MOVUPS (22*8)(SP), X13 \ + MOVUPS (24*8)(SP), X14 \ + MOVUPS (26*8)(SP), X15 \ + ADJSP $-(REGS_HOST_TO_ABI0_STACK - 8) \ + POPFQ + +#else +// SysV ABI + +#define REGS_HOST_TO_ABI0_STACK (6*8) + +// SysV MXCSR matches the Go ABI, so we don't have to set that, +// and Go doesn't modify it, so we don't have to save it. +// Both SysV and Go require DF to be cleared, so that's already clear. +// The SysV and Go frame pointer conventions are compatible. +#define PUSH_REGS_HOST_TO_ABI0() \ + ADJSP $(REGS_HOST_TO_ABI0_STACK) \ + MOVQ BP, (5*8)(SP) \ + LEAQ (5*8)(SP), BP \ + MOVQ BX, (0*8)(SP) \ + MOVQ R12, (1*8)(SP) \ + MOVQ R13, (2*8)(SP) \ + MOVQ R14, (3*8)(SP) \ + MOVQ R15, (4*8)(SP) + +#define POP_REGS_HOST_TO_ABI0() \ + MOVQ (0*8)(SP), BX \ + MOVQ (1*8)(SP), R12 \ + MOVQ (2*8)(SP), R13 \ + MOVQ (3*8)(SP), R14 \ + MOVQ (4*8)(SP), R15 \ + MOVQ (5*8)(SP), BP \ + ADJSP $-(REGS_HOST_TO_ABI0_STACK) + +#endif diff --git a/vendor/github.com/ebitengine/purego/abi_arm64.h b/vendor/github.com/ebitengine/purego/abi_arm64.h new file mode 100644 index 000000000..5d5061ec1 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/abi_arm64.h @@ -0,0 +1,39 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Macros for transitioning from the host ABI to Go ABI0. +// +// These macros save and restore the callee-saved registers +// from the stack, but they don't adjust stack pointer, so +// the user should prepare stack space in advance. +// SAVE_R19_TO_R28(offset) saves R19 ~ R28 to the stack space +// of ((offset)+0*8)(RSP) ~ ((offset)+9*8)(RSP). +// +// SAVE_F8_TO_F15(offset) saves F8 ~ F15 to the stack space +// of ((offset)+0*8)(RSP) ~ ((offset)+7*8)(RSP). +// +// R29 is not saved because Go will save and restore it. + +#define SAVE_R19_TO_R28(offset) \ + STP (R19, R20), ((offset)+0*8)(RSP) \ + STP (R21, R22), ((offset)+2*8)(RSP) \ + STP (R23, R24), ((offset)+4*8)(RSP) \ + STP (R25, R26), ((offset)+6*8)(RSP) \ + STP (R27, g), ((offset)+8*8)(RSP) +#define RESTORE_R19_TO_R28(offset) \ + LDP ((offset)+0*8)(RSP), (R19, R20) \ + LDP ((offset)+2*8)(RSP), (R21, R22) \ + LDP ((offset)+4*8)(RSP), (R23, R24) \ + LDP ((offset)+6*8)(RSP), (R25, R26) \ + LDP ((offset)+8*8)(RSP), (R27, g) /* R28 */ +#define SAVE_F8_TO_F15(offset) \ + FSTPD (F8, F9), ((offset)+0*8)(RSP) \ + FSTPD (F10, F11), ((offset)+2*8)(RSP) \ + FSTPD (F12, F13), ((offset)+4*8)(RSP) \ + FSTPD (F14, F15), ((offset)+6*8)(RSP) +#define RESTORE_F8_TO_F15(offset) \ + FLDPD ((offset)+0*8)(RSP), (F8, F9) \ + FLDPD ((offset)+2*8)(RSP), (F10, F11) \ + FLDPD ((offset)+4*8)(RSP), (F12, F13) \ + FLDPD ((offset)+6*8)(RSP), (F14, F15) diff --git a/vendor/github.com/ebitengine/purego/cgo.go b/vendor/github.com/ebitengine/purego/cgo.go new file mode 100644 index 000000000..32fe78235 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/cgo.go @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build cgo && (darwin || freebsd || linux) + +package purego + +// if CGO_ENABLED=1 import the Cgo runtime to ensure that it is set up properly. +// This is required since some frameworks need TLS setup the C way which Go doesn't do. +// We currently don't support ios in fakecgo mode so force Cgo or fail +// Even if CGO_ENABLED=1 the Cgo runtime is not imported unless `import "C"` is used. +// which will import this package automatically. Normally this isn't an issue since it +// usually isn't possible to call into C without using that import. However, with purego +// it is since we don't use `import "C"`! +import _ "runtime/cgo" diff --git a/vendor/github.com/ebitengine/purego/dlerror.go b/vendor/github.com/ebitengine/purego/dlerror.go new file mode 100644 index 000000000..cf4c0505d --- /dev/null +++ b/vendor/github.com/ebitengine/purego/dlerror.go @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 The Ebitengine Authors + +//go:build darwin || freebsd || linux + +package purego + +// Dlerror represents an error value returned from Dlopen, Dlsym, or Dlclose. +type Dlerror struct { + s string +} + +func (e Dlerror) Error() string { + return e.s +} diff --git a/vendor/github.com/ebitengine/purego/dlfcn.go b/vendor/github.com/ebitengine/purego/dlfcn.go new file mode 100644 index 000000000..2ee6f34b3 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/dlfcn.go @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || linux + +package purego + +import ( + "unsafe" +) + +// Unix Specification for dlfcn.h: https://pubs.opengroup.org/onlinepubs/7908799/xsh/dlfcn.h.html + +var ( + fnDlopen func(path string, mode int) uintptr + fnDlsym func(handle uintptr, name string) uintptr + fnDlerror func() string + fnDlclose func(handle uintptr) bool +) + +func init() { + RegisterFunc(&fnDlopen, dlopenABI0) + RegisterFunc(&fnDlsym, dlsymABI0) + RegisterFunc(&fnDlerror, dlerrorABI0) + RegisterFunc(&fnDlclose, dlcloseABI0) +} + +// Dlopen examines the dynamic library or bundle file specified by path. If the file is compatible +// with the current process and has not already been loaded into the +// current process, it is loaded and linked. After being linked, if it contains +// any initializer functions, they are called, before Dlopen +// returns. It returns a handle that can be used with Dlsym and Dlclose. +// A second call to Dlopen with the same path will return the same handle, but the internal +// reference count for the handle will be incremented. Therefore, all +// Dlopen calls should be balanced with a Dlclose call. +func Dlopen(path string, mode int) (uintptr, error) { + u := fnDlopen(path, mode) + if u == 0 { + return 0, Dlerror{fnDlerror()} + } + return u, nil +} + +// Dlsym takes a "handle" of a dynamic library returned by Dlopen and the symbol name. +// It returns the address where that symbol is loaded into memory. If the symbol is not found, +// in the specified library or any of the libraries that were automatically loaded by Dlopen +// when that library was loaded, Dlsym returns zero. +func Dlsym(handle uintptr, name string) (uintptr, error) { + u := fnDlsym(handle, name) + if u == 0 { + return 0, Dlerror{fnDlerror()} + } + return u, nil +} + +// Dlclose decrements the reference count on the dynamic library handle. +// If the reference count drops to zero and no other loaded libraries +// use symbols in it, then the dynamic library is unloaded. +func Dlclose(handle uintptr) error { + if fnDlclose(handle) { + return Dlerror{fnDlerror()} + } + return nil +} + +//go:linkname openLibrary openLibrary +func openLibrary(name string) (uintptr, error) { + return Dlopen(name, RTLD_NOW|RTLD_GLOBAL) +} + +func loadSymbol(handle uintptr, name string) (uintptr, error) { + return Dlsym(handle, name) +} + +// these functions exist in dlfcn_stubs.s and are calling C functions linked to in dlfcn_GOOS.go +// the indirection is necessary because a function is actually a pointer to the pointer to the code. +// sadly, I do not know of anyway to remove the assembly stubs entirely because //go:linkname doesn't +// appear to work if you link directly to the C function on darwin arm64. + +//go:linkname dlopen dlopen +var dlopen uintptr +var dlopenABI0 = uintptr(unsafe.Pointer(&dlopen)) + +//go:linkname dlsym dlsym +var dlsym uintptr +var dlsymABI0 = uintptr(unsafe.Pointer(&dlsym)) + +//go:linkname dlclose dlclose +var dlclose uintptr +var dlcloseABI0 = uintptr(unsafe.Pointer(&dlclose)) + +//go:linkname dlerror dlerror +var dlerror uintptr +var dlerrorABI0 = uintptr(unsafe.Pointer(&dlerror)) diff --git a/vendor/github.com/ebitengine/purego/dlfcn_darwin.go b/vendor/github.com/ebitengine/purego/dlfcn_darwin.go new file mode 100644 index 000000000..66ccf16d9 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/dlfcn_darwin.go @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +package purego + +// Source for constants: https://opensource.apple.com/source/dyld/dyld-360.14/include/dlfcn.h.auto.html + +const ( + RTLD_DEFAULT = ^uintptr(0) - 1 // Pseudo-handle for dlsym so search for any loaded symbol + RTLD_LAZY = 0x1 // Relocations are performed at an implementation-dependent time. + RTLD_NOW = 0x2 // Relocations are performed when the object is loaded. + RTLD_LOCAL = 0x4 // All symbols are not made available for relocation processing by other modules. + RTLD_GLOBAL = 0x8 // All symbols are available for relocation processing of other modules. +) + +//go:cgo_import_dynamic purego_dlopen dlopen "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_dlsym dlsym "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_dlerror dlerror "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_dlclose dlclose "/usr/lib/libSystem.B.dylib" diff --git a/vendor/github.com/ebitengine/purego/dlfcn_freebsd.go b/vendor/github.com/ebitengine/purego/dlfcn_freebsd.go new file mode 100644 index 000000000..b34b61f70 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/dlfcn_freebsd.go @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +package purego + +// Constants as defined in https://github.com/freebsd/freebsd-src/blob/main/include/dlfcn.h +const ( + RTLD_DEFAULT = ^uintptr(0) - 2 // Pseudo-handle for dlsym so search for any loaded symbol + RTLD_LAZY = 0x00001 // Relocations are performed at an implementation-dependent time. + RTLD_NOW = 0x00002 // Relocations are performed when the object is loaded. + RTLD_LOCAL = 0x00000 // All symbols are not made available for relocation processing by other modules. + RTLD_GLOBAL = 0x00100 // All symbols are available for relocation processing of other modules. +) + +//go:cgo_import_dynamic purego_dlopen dlopen "libc.so.7" +//go:cgo_import_dynamic purego_dlsym dlsym "libc.so.7" +//go:cgo_import_dynamic purego_dlerror dlerror "libc.so.7" +//go:cgo_import_dynamic purego_dlclose dlclose "libc.so.7" diff --git a/vendor/github.com/ebitengine/purego/dlfcn_linux.go b/vendor/github.com/ebitengine/purego/dlfcn_linux.go new file mode 100644 index 000000000..301127538 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/dlfcn_linux.go @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +package purego + +// Source for constants: https://codebrowser.dev/glibc/glibc/bits/dlfcn.h.html + +const ( + RTLD_DEFAULT = 0x00000 // Pseudo-handle for dlsym so search for any loaded symbol + RTLD_LAZY = 0x00001 // Relocations are performed at an implementation-dependent time. + RTLD_NOW = 0x00002 // Relocations are performed when the object is loaded. + RTLD_LOCAL = 0x00000 // All symbols are not made available for relocation processing by other modules. + RTLD_GLOBAL = 0x00100 // All symbols are available for relocation processing of other modules. +) diff --git a/vendor/github.com/ebitengine/purego/dlfcn_nocgo_linux.go b/vendor/github.com/ebitengine/purego/dlfcn_nocgo_linux.go new file mode 100644 index 000000000..2c8009fdb --- /dev/null +++ b/vendor/github.com/ebitengine/purego/dlfcn_nocgo_linux.go @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build !cgo + +package purego + +// if there is no Cgo we must link to each of the functions from dlfcn.h +// then the functions are called inside dlfcn_stubs.s + +//go:cgo_import_dynamic purego_dlopen dlopen "libdl.so.2" +//go:cgo_import_dynamic purego_dlsym dlsym "libdl.so.2" +//go:cgo_import_dynamic purego_dlerror dlerror "libdl.so.2" +//go:cgo_import_dynamic purego_dlclose dlclose "libdl.so.2" + +// on amd64 we don't need the following line - on 386 we do... +// anyway - with those lines the output is better (but doesn't matter) - without it on amd64 we get multiple DT_NEEDED with "libc.so.6" etc + +//go:cgo_import_dynamic _ _ "libdl.so.2" diff --git a/vendor/github.com/ebitengine/purego/dlfcn_stubs.s b/vendor/github.com/ebitengine/purego/dlfcn_stubs.s new file mode 100644 index 000000000..d8c6eea3c --- /dev/null +++ b/vendor/github.com/ebitengine/purego/dlfcn_stubs.s @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || (linux && !cgo) + +#include "textflag.h" + +// func dlopen(path *byte, mode int) (ret uintptr) +TEXT dlopen(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_dlopen(SB) + RET + +// func dlsym(handle uintptr, symbol *byte) (ret uintptr) +TEXT dlsym(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_dlsym(SB) + RET + +// func dlerror() (ret *byte) +TEXT dlerror(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_dlerror(SB) + RET + +// func dlclose(handle uintptr) (ret int) +TEXT dlclose(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_dlclose(SB) + RET diff --git a/vendor/github.com/ebitengine/purego/func.go b/vendor/github.com/ebitengine/purego/func.go new file mode 100644 index 000000000..48677850d --- /dev/null +++ b/vendor/github.com/ebitengine/purego/func.go @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || linux || windows + +package purego + +import ( + "math" + "reflect" + "runtime" + "unsafe" + + "github.com/ebitengine/purego/internal/strings" +) + +// RegisterLibFunc is a wrapper around RegisterFunc that uses the C function returned from Dlsym(handle, name). +// It panics if it can't find the name symbol. +func RegisterLibFunc(fptr interface{}, handle uintptr, name string) { + sym, err := loadSymbol(handle, name) + if err != nil { + panic(err) + } + RegisterFunc(fptr, sym) +} + +// RegisterFunc takes a pointer to a Go function representing the calling convention of the C function. +// fptr will be set to a function that when called will call the C function given by cfn with the +// parameters passed in the correct registers and stack. +// +// A panic is produced if the type is not a function pointer or if the function returns more than 1 value. +// +// These conversions describe how a Go type in the fptr will be used to call +// the C function. It is important to note that there is no way to verify that fptr +// matches the C function. This also holds true for struct types where the padding +// needs to be ensured to match that of C; RegisterFunc does not verify this. +// +// # Type Conversions (Go <=> C) +// +// string <=> char* +// bool <=> _Bool +// uintptr <=> uintptr_t +// uint <=> uint32_t or uint64_t +// uint8 <=> uint8_t +// uint16 <=> uint16_t +// uint32 <=> uint32_t +// uint64 <=> uint64_t +// int <=> int32_t or int64_t +// int8 <=> int8_t +// int16 <=> int16_t +// int32 <=> int32_t +// int64 <=> int64_t +// float32 <=> float (WIP) +// float64 <=> double (WIP) +// struct <=> struct (WIP) +// func <=> C function +// unsafe.Pointer, *T <=> void* +// []T => void* +// +// There is a special case when the last argument of fptr is a variadic interface (or []interface} +// it will be expanded into a call to the C function as if it had the arguments in that slice. +// This means that using arg ...interface{} is like a cast to the function with the arguments inside arg. +// This is not the same as C variadic. +// +// There are some limitations when using RegisterFunc on Linux. First, there is no support for function arguments. +// Second, float32 and float64 arguments and return values do not work when CGO_ENABLED=1. Otherwise, Linux +// has the same feature parity as Darwin. +// +// # Memory +// +// In general it is not possible for purego to guarantee the lifetimes of objects returned or received from +// calling functions using RegisterFunc. For arguments to a C function it is important that the C function doesn't +// hold onto a reference to Go memory. This is the same as the [Cgo rules]. +// +// However, there are some special cases. When passing a string as an argument if the string does not end in a null +// terminated byte (\x00) then the string will be copied into memory maintained by purego. The memory is only valid for +// that specific call. Therefore, if the C code keeps a reference to that string it may become invalid at some +// undefined time. However, if the string does already contain a null-terminated byte then no copy is done. +// It is then the responsibility of the caller to ensure the string stays alive as long as it's needed in C memory. +// This can be done using runtime.KeepAlive or allocating the string in C memory using malloc. When a C function +// returns a null-terminated pointer to char a Go string can be used. Purego will allocate a new string in Go memory +// and copy the data over. This string will be garbage collected whenever Go decides it's no longer referenced. +// This C created string will not be freed by purego. If the pointer to char is not null-terminated or must continue +// to point to C memory (because it's a buffer for example) then use a pointer to byte and then convert that to a slice +// using unsafe.Slice. Doing this means that it becomes the responsibility of the caller to care about the lifetime +// of the pointer +// +// # Example +// +// All functions below call this C function: +// +// char *foo(char *str); +// +// // Let purego convert types +// var foo func(s string) string +// goString := foo("copied") +// // Go will garbage collect this string +// +// // Manually, handle allocations +// var foo2 func(b string) *byte +// mustFree := foo2("not copied\x00") +// defer free(mustFree) +// +// [Cgo rules]: https://pkg.go.dev/cmd/cgo#hdr-Go_references_to_C +func RegisterFunc(fptr interface{}, cfn uintptr) { + fn := reflect.ValueOf(fptr).Elem() + ty := fn.Type() + if ty.Kind() != reflect.Func { + panic("purego: fptr must be a function pointer") + } + if ty.NumOut() > 1 { + panic("purego: function can only return zero or one values") + } + if cfn == 0 { + panic("purego: cfn is nil") + } + { + // this code checks how many registers and stack this function will use + // to avoid crashing with too many arguments + var ints int + var floats int + var stack int + for i := 0; i < ty.NumIn(); i++ { + arg := ty.In(i) + switch arg.Kind() { + case reflect.String, reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Ptr, reflect.UnsafePointer, reflect.Slice, + reflect.Func, reflect.Bool: + if ints < numOfIntegerRegisters() { + ints++ + } else { + stack++ + } + case reflect.Float32, reflect.Float64: + if floats < numOfFloats { + floats++ + } else { + stack++ + } + default: + panic("purego: unsupported kind " + arg.Kind().String()) + } + } + sizeOfStack := maxArgs - numOfIntegerRegisters() + if stack > sizeOfStack { + panic("purego: too many arguments") + } + } + v := reflect.MakeFunc(ty, func(args []reflect.Value) (results []reflect.Value) { + if len(args) > 0 { + if variadic, ok := args[len(args)-1].Interface().([]interface{}); ok { + // subtract one from args bc the last argument in args is []interface{} + // which we are currently expanding + tmp := make([]reflect.Value, len(args)-1+len(variadic)) + n := copy(tmp, args[:len(args)-1]) + for i, v := range variadic { + tmp[n+i] = reflect.ValueOf(v) + } + args = tmp + } + } + var sysargs [maxArgs]uintptr + stack := sysargs[numOfIntegerRegisters():] + var floats [numOfFloats]uintptr + var numInts int + var numFloats int + var numStack int + var addStack, addInt, addFloat func(x uintptr) + if runtime.GOARCH == "arm64" || runtime.GOOS != "windows" { + // Windows arm64 uses the same calling convention as macOS and Linux + addStack = func(x uintptr) { + stack[numStack] = x + numStack++ + } + addInt = func(x uintptr) { + if numInts >= numOfIntegerRegisters() { + addStack(x) + } else { + sysargs[numInts] = x + numInts++ + } + } + addFloat = func(x uintptr) { + if numFloats < len(floats) { + floats[numFloats] = x + numFloats++ + } else { + addStack(x) + } + } + } else { + // On Windows amd64 the arguments are passed in the numbered registered. + // So the first int is in the first integer register and the first float + // is in the second floating register if there is already a first int. + // This is in contrast to how macOS and Linux pass arguments which + // tries to use as many registers as possible in the calling convention. + addStack = func(x uintptr) { + sysargs[numStack] = x + numStack++ + } + addInt = addStack + addFloat = addStack + } + + var keepAlive []interface{} + defer func() { + runtime.KeepAlive(keepAlive) + runtime.KeepAlive(args) + }() + for _, v := range args { + switch v.Kind() { + case reflect.String: + ptr := strings.CString(v.String()) + keepAlive = append(keepAlive, ptr) + addInt(uintptr(unsafe.Pointer(ptr))) + case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + addInt(uintptr(v.Uint())) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + addInt(uintptr(v.Int())) + case reflect.Ptr, reflect.UnsafePointer, reflect.Slice: + // There is no need to keepAlive this pointer separately because it is kept alive in the args variable + addInt(v.Pointer()) + case reflect.Func: + addInt(NewCallback(v.Interface())) + case reflect.Bool: + if v.Bool() { + addInt(1) + } else { + addInt(0) + } + case reflect.Float32: + addFloat(uintptr(math.Float32bits(float32(v.Float())))) + case reflect.Float64: + addFloat(uintptr(math.Float64bits(v.Float()))) + default: + panic("purego: unsupported kind: " + v.Kind().String()) + } + } + // TODO: support structs + var r1, r2 uintptr + if runtime.GOARCH == "arm64" || runtime.GOOS != "windows" { + // Use the normal arm64 calling convention even on Windows + syscall := syscall9Args{ + cfn, + sysargs[0], sysargs[1], sysargs[2], sysargs[3], sysargs[4], sysargs[5], sysargs[6], sysargs[7], sysargs[8], + floats[0], floats[1], floats[2], floats[3], floats[4], floats[5], floats[6], floats[7], + 0, 0, 0, + } + runtime_cgocall(syscall9XABI0, unsafe.Pointer(&syscall)) + r1, r2 = syscall.r1, syscall.r2 + } else { + // This is a fallback for amd64, 386, and arm. Note this may not support floats + r1, r2, _ = syscall_syscall9X(cfn, sysargs[0], sysargs[1], sysargs[2], sysargs[3], sysargs[4], sysargs[5], sysargs[6], sysargs[7], sysargs[8]) + } + if ty.NumOut() == 0 { + return nil + } + outType := ty.Out(0) + v := reflect.New(outType).Elem() + switch outType.Kind() { + case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + v.SetUint(uint64(r1)) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + v.SetInt(int64(r1)) + case reflect.Bool: + v.SetBool(r1 != 0) + case reflect.UnsafePointer: + // We take the address and then dereference it to trick go vet from creating a possible miss-use of unsafe.Pointer + v.SetPointer(*(*unsafe.Pointer)(unsafe.Pointer(&r1))) + case reflect.Ptr: + // It is safe to have the address of r1 not escape because it is immediately dereferenced with .Elem() + v = reflect.NewAt(outType, runtime_noescape(unsafe.Pointer(&r1))).Elem() + case reflect.Func: + // wrap this C function in a nicely typed Go function + v = reflect.New(outType) + RegisterFunc(v.Interface(), r1) + case reflect.String: + v.SetString(strings.GoString(r1)) + case reflect.Float32, reflect.Float64: + // NOTE: r2 is only the floating return value on 64bit platforms. + // On 32bit platforms r2 is the upper part of a 64bit return. + v.SetFloat(math.Float64frombits(uint64(r2))) + default: + panic("purego: unsupported return kind: " + outType.Kind().String()) + } + return []reflect.Value{v} + }) + fn.Set(v) +} + +func numOfIntegerRegisters() int { + switch runtime.GOARCH { + case "arm64": + return 8 + case "amd64": + return 6 + // TODO: figure out why 386 tests are not working + /*case "386": + return 0 + case "arm": + return 4*/ + default: + panic("purego: unknown GOARCH (" + runtime.GOARCH + ")") + } +} diff --git a/vendor/github.com/ebitengine/purego/go_runtime.go b/vendor/github.com/ebitengine/purego/go_runtime.go new file mode 100644 index 000000000..9593dac90 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/go_runtime.go @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || linux || windows + +package purego + +import ( + "unsafe" +) + +//go:linkname runtime_cgocall runtime.cgocall +func runtime_cgocall(fn uintptr, arg unsafe.Pointer) int32 // from runtime/sys_libc.go + +//go:linkname runtime_noescape runtime.noescape +//go:noescape +func runtime_noescape(p unsafe.Pointer) unsafe.Pointer // from runtime/stubs.go diff --git a/vendor/github.com/ebitengine/purego/internal/cgo/syscall_cgo_unix.go b/vendor/github.com/ebitengine/purego/internal/cgo/syscall_cgo_unix.go new file mode 100644 index 000000000..9a4538de8 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/cgo/syscall_cgo_unix.go @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build freebsd || linux + +package cgo + +// this file is placed inside internal/cgo and not package purego +// because Cgo and assembly files can't be in the same package. + +/* + #cgo LDFLAGS: -ldl + +#include +#include +#include +#include + +typedef struct syscall9Args { + uintptr_t fn; + uintptr_t a1, a2, a3, a4, a5, a6, a7, a8, a9; + uintptr_t f1, f2, f3, f4, f5, f6, f7, f8; + uintptr_t r1, r2, err; +} syscall9Args; + +void syscall9(struct syscall9Args *args) { + assert((args->f1|args->f2|args->f3|args->f4|args->f5|args->f6|args->f7|args->f8) == 0); + uintptr_t (*func_name)(uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9); + *(void**)(&func_name) = (void*)(args->fn); + uintptr_t r1 = func_name(args->a1,args->a2,args->a3,args->a4,args->a5,args->a6,args->a7,args->a8,args->a9); + args->r1 = r1; + args->err = errno; +} + +*/ +import "C" +import "unsafe" + +// assign purego.syscall9XABI0 to the C version of this function. +var Syscall9XABI0 = unsafe.Pointer(C.syscall9) + +// all that is needed is to assign each dl function because then its +// symbol will then be made available to the linker and linked to inside dlfcn.go +var ( + _ = C.dlopen + _ = C.dlsym + _ = C.dlerror + _ = C.dlclose +) + +//go:nosplit +func Syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) { + args := C.syscall9Args{C.uintptr_t(fn), C.uintptr_t(a1), C.uintptr_t(a2), C.uintptr_t(a3), + C.uintptr_t(a4), C.uintptr_t(a5), C.uintptr_t(a6), + C.uintptr_t(a7), C.uintptr_t(a8), C.uintptr_t(a9), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + C.syscall9(&args) + return uintptr(args.r1), uintptr(args.r2), uintptr(args.err) +} diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/abi_amd64.h b/vendor/github.com/ebitengine/purego/internal/fakecgo/abi_amd64.h new file mode 100644 index 000000000..9949435fe --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/abi_amd64.h @@ -0,0 +1,99 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Macros for transitioning from the host ABI to Go ABI0. +// +// These save the frame pointer, so in general, functions that use +// these should have zero frame size to suppress the automatic frame +// pointer, though it's harmless to not do this. + +#ifdef GOOS_windows + +// REGS_HOST_TO_ABI0_STACK is the stack bytes used by +// PUSH_REGS_HOST_TO_ABI0. +#define REGS_HOST_TO_ABI0_STACK (28*8 + 8) + +// PUSH_REGS_HOST_TO_ABI0 prepares for transitioning from +// the host ABI to Go ABI0 code. It saves all registers that are +// callee-save in the host ABI and caller-save in Go ABI0 and prepares +// for entry to Go. +// +// Save DI SI BP BX R12 R13 R14 R15 X6-X15 registers and the DF flag. +// Clear the DF flag for the Go ABI. +// MXCSR matches the Go ABI, so we don't have to set that, +// and Go doesn't modify it, so we don't have to save it. +#define PUSH_REGS_HOST_TO_ABI0() \ + PUSHFQ \ + CLD \ + ADJSP $(REGS_HOST_TO_ABI0_STACK - 8) \ + MOVQ DI, (0*0)(SP) \ + MOVQ SI, (1*8)(SP) \ + MOVQ BP, (2*8)(SP) \ + MOVQ BX, (3*8)(SP) \ + MOVQ R12, (4*8)(SP) \ + MOVQ R13, (5*8)(SP) \ + MOVQ R14, (6*8)(SP) \ + MOVQ R15, (7*8)(SP) \ + MOVUPS X6, (8*8)(SP) \ + MOVUPS X7, (10*8)(SP) \ + MOVUPS X8, (12*8)(SP) \ + MOVUPS X9, (14*8)(SP) \ + MOVUPS X10, (16*8)(SP) \ + MOVUPS X11, (18*8)(SP) \ + MOVUPS X12, (20*8)(SP) \ + MOVUPS X13, (22*8)(SP) \ + MOVUPS X14, (24*8)(SP) \ + MOVUPS X15, (26*8)(SP) + +#define POP_REGS_HOST_TO_ABI0() \ + MOVQ (0*0)(SP), DI \ + MOVQ (1*8)(SP), SI \ + MOVQ (2*8)(SP), BP \ + MOVQ (3*8)(SP), BX \ + MOVQ (4*8)(SP), R12 \ + MOVQ (5*8)(SP), R13 \ + MOVQ (6*8)(SP), R14 \ + MOVQ (7*8)(SP), R15 \ + MOVUPS (8*8)(SP), X6 \ + MOVUPS (10*8)(SP), X7 \ + MOVUPS (12*8)(SP), X8 \ + MOVUPS (14*8)(SP), X9 \ + MOVUPS (16*8)(SP), X10 \ + MOVUPS (18*8)(SP), X11 \ + MOVUPS (20*8)(SP), X12 \ + MOVUPS (22*8)(SP), X13 \ + MOVUPS (24*8)(SP), X14 \ + MOVUPS (26*8)(SP), X15 \ + ADJSP $-(REGS_HOST_TO_ABI0_STACK - 8) \ + POPFQ + +#else +// SysV ABI + +#define REGS_HOST_TO_ABI0_STACK (6*8) + +// SysV MXCSR matches the Go ABI, so we don't have to set that, +// and Go doesn't modify it, so we don't have to save it. +// Both SysV and Go require DF to be cleared, so that's already clear. +// The SysV and Go frame pointer conventions are compatible. +#define PUSH_REGS_HOST_TO_ABI0() \ + ADJSP $(REGS_HOST_TO_ABI0_STACK) \ + MOVQ BP, (5*8)(SP) \ + LEAQ (5*8)(SP), BP \ + MOVQ BX, (0*8)(SP) \ + MOVQ R12, (1*8)(SP) \ + MOVQ R13, (2*8)(SP) \ + MOVQ R14, (3*8)(SP) \ + MOVQ R15, (4*8)(SP) + +#define POP_REGS_HOST_TO_ABI0() \ + MOVQ (0*8)(SP), BX \ + MOVQ (1*8)(SP), R12 \ + MOVQ (2*8)(SP), R13 \ + MOVQ (3*8)(SP), R14 \ + MOVQ (4*8)(SP), R15 \ + MOVQ (5*8)(SP), BP \ + ADJSP $-(REGS_HOST_TO_ABI0_STACK) + +#endif diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/abi_arm64.h b/vendor/github.com/ebitengine/purego/internal/fakecgo/abi_arm64.h new file mode 100644 index 000000000..5d5061ec1 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/abi_arm64.h @@ -0,0 +1,39 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Macros for transitioning from the host ABI to Go ABI0. +// +// These macros save and restore the callee-saved registers +// from the stack, but they don't adjust stack pointer, so +// the user should prepare stack space in advance. +// SAVE_R19_TO_R28(offset) saves R19 ~ R28 to the stack space +// of ((offset)+0*8)(RSP) ~ ((offset)+9*8)(RSP). +// +// SAVE_F8_TO_F15(offset) saves F8 ~ F15 to the stack space +// of ((offset)+0*8)(RSP) ~ ((offset)+7*8)(RSP). +// +// R29 is not saved because Go will save and restore it. + +#define SAVE_R19_TO_R28(offset) \ + STP (R19, R20), ((offset)+0*8)(RSP) \ + STP (R21, R22), ((offset)+2*8)(RSP) \ + STP (R23, R24), ((offset)+4*8)(RSP) \ + STP (R25, R26), ((offset)+6*8)(RSP) \ + STP (R27, g), ((offset)+8*8)(RSP) +#define RESTORE_R19_TO_R28(offset) \ + LDP ((offset)+0*8)(RSP), (R19, R20) \ + LDP ((offset)+2*8)(RSP), (R21, R22) \ + LDP ((offset)+4*8)(RSP), (R23, R24) \ + LDP ((offset)+6*8)(RSP), (R25, R26) \ + LDP ((offset)+8*8)(RSP), (R27, g) /* R28 */ +#define SAVE_F8_TO_F15(offset) \ + FSTPD (F8, F9), ((offset)+0*8)(RSP) \ + FSTPD (F10, F11), ((offset)+2*8)(RSP) \ + FSTPD (F12, F13), ((offset)+4*8)(RSP) \ + FSTPD (F14, F15), ((offset)+6*8)(RSP) +#define RESTORE_F8_TO_F15(offset) \ + FLDPD ((offset)+0*8)(RSP), (F8, F9) \ + FLDPD ((offset)+2*8)(RSP), (F10, F11) \ + FLDPD ((offset)+4*8)(RSP), (F12, F13) \ + FLDPD ((offset)+6*8)(RSP), (F14, F15) diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/asm_amd64.s b/vendor/github.com/ebitengine/purego/internal/fakecgo/asm_amd64.s new file mode 100644 index 000000000..1ad925475 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/asm_amd64.s @@ -0,0 +1,39 @@ +// 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. + +#include "textflag.h" +#include "abi_amd64.h" + +// Called by C code generated by cmd/cgo. +// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr) +// Saves C callee-saved registers and calls cgocallback with three arguments. +// fn is the PC of a func(a unsafe.Pointer) function. +// This signature is known to SWIG, so we can't change it. +TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0-0 + PUSH_REGS_HOST_TO_ABI0() + + // Make room for arguments to cgocallback. + ADJSP $0x18 + +#ifndef GOOS_windows + MOVQ DI, 0x0(SP) // fn + MOVQ SI, 0x8(SP) // arg + + // Skip n in DX. + MOVQ CX, 0x10(SP) // ctxt + +#else + MOVQ CX, 0x0(SP) // fn + MOVQ DX, 0x8(SP) // arg + + // Skip n in R8. + MOVQ R9, 0x10(SP) // ctxt + +#endif + + CALL runtime·cgocallback(SB) + + ADJSP $-0x18 + POP_REGS_HOST_TO_ABI0() + RET diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/asm_arm64.s b/vendor/github.com/ebitengine/purego/internal/fakecgo/asm_arm64.s new file mode 100644 index 000000000..50e5261d9 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/asm_arm64.s @@ -0,0 +1,36 @@ +// Copyright 2015 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. + +#include "textflag.h" +#include "abi_arm64.h" + +// Called by C code generated by cmd/cgo. +// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr) +// Saves C callee-saved registers and calls cgocallback with three arguments. +// fn is the PC of a func(a unsafe.Pointer) function. +TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0 +/* + * We still need to save all callee save register as before, and then + * push 3 args for fn (R0, R1, R3), skipping R2. + * Also note that at procedure entry in gc world, 8(RSP) will be the + * first arg. + */ + SUB $(8*24), RSP + STP (R0, R1), (8*1)(RSP) + MOVD R3, (8*3)(RSP) + + SAVE_R19_TO_R28(8*4) + SAVE_F8_TO_F15(8*14) + STP (R29, R30), (8*22)(RSP) + + // Initialize Go ABI environment + BL runtime·load_g(SB) + BL runtime·cgocallback(SB) + + RESTORE_R19_TO_R28(8*4) + RESTORE_F8_TO_F15(8*14) + LDP (8*22)(RSP), (R29, R30) + + ADD $(8*24), RSP + RET diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/callbacks.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/callbacks.go new file mode 100644 index 000000000..f6a079a7c --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/callbacks.go @@ -0,0 +1,93 @@ +// Copyright 2011 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 darwin || freebsd || linux + +package fakecgo + +import ( + _ "unsafe" +) + +// TODO: decide if we need _runtime_cgo_panic_internal + +//go:linkname x_cgo_init_trampoline x_cgo_init_trampoline +//go:linkname _cgo_init _cgo_init +var x_cgo_init_trampoline byte +var _cgo_init = &x_cgo_init_trampoline + +// Creates a new system thread without updating any Go state. +// +// This method is invoked during shared library loading to create a new OS +// thread to perform the runtime initialization. This method is similar to +// _cgo_sys_thread_start except that it doesn't update any Go state. + +//go:linkname x_cgo_thread_start_trampoline x_cgo_thread_start_trampoline +//go:linkname _cgo_thread_start _cgo_thread_start +var x_cgo_thread_start_trampoline byte +var _cgo_thread_start = &x_cgo_thread_start_trampoline + +// Notifies that the runtime has been initialized. +// +// We currently block at every CGO entry point (via _cgo_wait_runtime_init_done) +// to ensure that the runtime has been initialized before the CGO call is +// executed. This is necessary for shared libraries where we kickoff runtime +// initialization in a separate thread and return without waiting for this +// thread to complete the init. + +//go:linkname x_cgo_notify_runtime_init_done_trampoline x_cgo_notify_runtime_init_done_trampoline +//go:linkname _cgo_notify_runtime_init_done _cgo_notify_runtime_init_done +var x_cgo_notify_runtime_init_done_trampoline byte +var _cgo_notify_runtime_init_done = &x_cgo_notify_runtime_init_done_trampoline + +// Indicates whether a dummy thread key has been created or not. +// +// When calling go exported function from C, we register a destructor +// callback, for a dummy thread key, by using pthread_key_create. + +//go:linkname _cgo_pthread_key_created _cgo_pthread_key_created +var x_cgo_pthread_key_created uintptr +var _cgo_pthread_key_created = &x_cgo_pthread_key_created + +// Set the x_crosscall2_ptr C function pointer variable point to crosscall2. +// It's for the runtime package to call at init time. +func set_crosscall2() { + // nothing needs to be done here for fakecgo + // because it's possible to just call cgocallback directly +} + +//go:linkname _set_crosscall2 runtime.set_crosscall2 +var _set_crosscall2 = set_crosscall2 + +// Store the g into the thread-specific value. +// So that pthread_key_destructor will dropm when the thread is exiting. + +//go:linkname x_cgo_bindm_trampoline x_cgo_bindm_trampoline +//go:linkname _cgo_bindm _cgo_bindm +var x_cgo_bindm_trampoline byte +var _cgo_bindm = &x_cgo_bindm_trampoline + +// TODO: decide if we need x_cgo_set_context_function +// TODO: decide if we need _cgo_yield + +var ( + // In Go 1.20 the race detector was rewritten to pure Go + // on darwin. This means that when CGO_ENABLED=0 is set + // fakecgo is built with race detector code. This is not + // good since this code is pretending to be C. The go:norace + // pragma is not enough, since it only applies to the native + // ABIInternal function. The ABIO wrapper (which is necessary, + // since all references to text symbols from assembly will use it) + // does not inherit the go:norace pragma, so it will still be + // instrumented by the race detector. + // + // To circumvent this issue, using closure calls in the + // assembly, which forces the compiler to use the ABIInternal + // native implementation (which has go:norace) instead. + threadentry_call = threadentry + x_cgo_init_call = x_cgo_init + x_cgo_setenv_call = x_cgo_setenv + x_cgo_unsetenv_call = x_cgo_unsetenv + x_cgo_thread_start_call = x_cgo_thread_start +) diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/doc.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/doc.go new file mode 100644 index 000000000..efbe4212e --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/doc.go @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd + +// Package fakecgo implements the Cgo runtime (runtime/cgo) entirely in Go. +// This allows code that calls into C to function properly when CGO_ENABLED=0. +// +// # Goals +// +// fakecgo attempts to replicate the same naming structure as in the runtime. +// For example, functions that have the prefix "gcc_*" are named "go_*". +// This makes it easier to port other GOOSs and GOARCHs as well as to keep +// it in sync with runtime/cgo. +// +// # Support +// +// Currently, fakecgo only supports macOS on amd64 & arm64. It also cannot +// be used with -buildmode=c-archive because that requires special initialization +// that fakecgo does not implement at the moment. +// +// # Usage +// +// Using fakecgo is easy just import _ "github.com/ebitengine/purego" and then +// set the environment variable CGO_ENABLED=0. +// The recommended usage for fakecgo is to prefer using runtime/cgo if possible +// but if cross-compiling or fast build times are important fakecgo is available. +// Purego will pick which ever Cgo runtime is available and prefer the one that +// comes with Go (runtime/cgo). +package fakecgo + +//go:generate go run gen.go +//go:generate gofmt -s -w symbols.go diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/freebsd.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/freebsd.go new file mode 100644 index 000000000..bb73a709e --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/freebsd.go @@ -0,0 +1,27 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build freebsd && !cgo + +package fakecgo + +import _ "unsafe" // for go:linkname + +// Supply environ and __progname, because we don't +// link against the standard FreeBSD crt0.o and the +// libc dynamic library needs them. + +// Note: when building with cross-compiling or CGO_ENABLED=0, add +// the following argument to `go` so that these symbols are defined by +// making fakecgo the Cgo. +// -gcflags="github.com/ebitengine/purego/internal/fakecgo=-std" + +//go:linkname _environ environ +//go:linkname _progname __progname + +//go:cgo_export_dynamic environ +//go:cgo_export_dynamic __progname + +var _environ uintptr +var _progname uintptr diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/go_darwin_amd64.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_darwin_amd64.go new file mode 100644 index 000000000..fb3a3f7f0 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_darwin_amd64.go @@ -0,0 +1,71 @@ +// Copyright 2011 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 fakecgo + +import "unsafe" + +//go:nosplit +//go:norace +func _cgo_sys_thread_start(ts *ThreadStart) { + var attr pthread_attr_t + var ign, oset sigset_t + var p pthread_t + var size size_t + var err int + + sigfillset(&ign) + pthread_sigmask(SIG_SETMASK, &ign, &oset) + + size = pthread_get_stacksize_np(pthread_self()) + pthread_attr_init(&attr) + pthread_attr_setstacksize(&attr, size) + // Leave stacklo=0 and set stackhi=size; mstart will do the rest. + ts.g.stackhi = uintptr(size) + + err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts) + + pthread_sigmask(SIG_SETMASK, &oset, nil) + + if err != 0 { + print("fakecgo: pthread_create failed: ") + println(err) + abort() + } +} + +// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function +// +//go:linkname x_threadentry_trampoline threadentry_trampoline +var x_threadentry_trampoline byte +var threadentry_trampolineABI0 = &x_threadentry_trampoline + +//go:nosplit +//go:norace +func threadentry(v unsafe.Pointer) unsafe.Pointer { + ts := *(*ThreadStart)(v) + free(v) + + setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g))) + + // faking funcs in go is a bit a... involved - but the following works :) + fn := uintptr(unsafe.Pointer(&ts.fn)) + (*(*func())(unsafe.Pointer(&fn)))() + + return nil +} + +// here we will store a pointer to the provided setg func +var setg_func uintptr + +//go:nosplit +//go:norace +func x_cgo_init(g *G, setg uintptr) { + var size size_t + + setg_func = setg + + size = pthread_get_stacksize_np(pthread_self()) + g.stacklo = uintptr(unsafe.Add(unsafe.Pointer(&size), -size+4096)) +} diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/go_darwin_arm64.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_darwin_arm64.go new file mode 100644 index 000000000..b000b3fbf --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_darwin_arm64.go @@ -0,0 +1,86 @@ +// Copyright 2011 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 fakecgo + +import "unsafe" + +//go:nosplit +//go:norace +func _cgo_sys_thread_start(ts *ThreadStart) { + var attr pthread_attr_t + var ign, oset sigset_t + var p pthread_t + var size size_t + var err int + + sigfillset(&ign) + pthread_sigmask(SIG_SETMASK, &ign, &oset) + + size = pthread_get_stacksize_np(pthread_self()) + pthread_attr_init(&attr) + pthread_attr_setstacksize(&attr, size) + // Leave stacklo=0 and set stackhi=size; mstart will do the rest. + ts.g.stackhi = uintptr(size) + + err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts) + + pthread_sigmask(SIG_SETMASK, &oset, nil) + + if err != 0 { + print("fakecgo: pthread_create failed: ") + println(err) + abort() + } +} + +// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function +// +//go:linkname x_threadentry_trampoline threadentry_trampoline +var x_threadentry_trampoline byte +var threadentry_trampolineABI0 = &x_threadentry_trampoline + +//go:nosplit +//go:norace +func threadentry(v unsafe.Pointer) unsafe.Pointer { + ts := *(*ThreadStart)(v) + free(v) + + // TODO: support ios + //#if TARGET_OS_IPHONE + // darwin_arm_init_thread_exception_port(); + //#endif + setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g))) + + // faking funcs in go is a bit a... involved - but the following works :) + fn := uintptr(unsafe.Pointer(&ts.fn)) + (*(*func())(unsafe.Pointer(&fn)))() + + return nil +} + +// here we will store a pointer to the provided setg func +var setg_func uintptr + +// x_cgo_init(G *g, void (*setg)(void*)) (runtime/cgo/gcc_linux_amd64.c) +// This get's called during startup, adjusts stacklo, and provides a pointer to setg_gcc for us +// Additionally, if we set _cgo_init to non-null, go won't do it's own TLS setup +// This function can't be go:systemstack since go is not in a state where the systemcheck would work. +// +//go:nosplit +//go:norace +func x_cgo_init(g *G, setg uintptr) { + var size size_t + + setg_func = setg + size = pthread_get_stacksize_np(pthread_self()) + g.stacklo = uintptr(unsafe.Add(unsafe.Pointer(&size), -size+4096)) + + //TODO: support ios + //#if TARGET_OS_IPHONE + // darwin_arm_init_mach_exception_handler(); + // darwin_arm_init_thread_exception_port(); + // init_working_dir(); + //#endif +} diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/go_freebsd_amd64.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_freebsd_amd64.go new file mode 100644 index 000000000..9aa57ef66 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_freebsd_amd64.go @@ -0,0 +1,93 @@ +// Copyright 2011 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 fakecgo + +import "unsafe" + +//go:nosplit +func _cgo_sys_thread_start(ts *ThreadStart) { + var attr pthread_attr_t + var ign, oset sigset_t + var p pthread_t + var size size_t + var err int + + //fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug + sigfillset(&ign) + pthread_sigmask(SIG_SETMASK, &ign, &oset) + + pthread_attr_init(&attr) + pthread_attr_getstacksize(&attr, &size) + // Leave stacklo=0 and set stackhi=size; mstart will do the rest. + ts.g.stackhi = uintptr(size) + + err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts) + + pthread_sigmask(SIG_SETMASK, &oset, nil) + + if err != 0 { + print("fakecgo: pthread_create failed: ") + println(err) + abort() + } +} + +// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function +// +//go:linkname x_threadentry_trampoline threadentry_trampoline +var x_threadentry_trampoline byte +var threadentry_trampolineABI0 = &x_threadentry_trampoline + +//go:nosplit +func threadentry(v unsafe.Pointer) unsafe.Pointer { + ts := *(*ThreadStart)(v) + free(v) + + setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g))) + + // faking funcs in go is a bit a... involved - but the following works :) + fn := uintptr(unsafe.Pointer(&ts.fn)) + (*(*func())(unsafe.Pointer(&fn)))() + + return nil +} + +// here we will store a pointer to the provided setg func +var setg_func uintptr + +//go:nosplit +func x_cgo_init(g *G, setg uintptr) { + var size size_t + var attr *pthread_attr_t + + /* The memory sanitizer distributed with versions of clang + before 3.8 has a bug: if you call mmap before malloc, mmap + may return an address that is later overwritten by the msan + library. Avoid this problem by forcing a call to malloc + here, before we ever call malloc. + + This is only required for the memory sanitizer, so it's + unfortunate that we always run it. It should be possible + to remove this when we no longer care about versions of + clang before 3.8. The test for this is + misc/cgo/testsanitizers. + + GCC works hard to eliminate a seemingly unnecessary call to + malloc, so we actually use the memory we allocate. */ + + setg_func = setg + attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr))) + if attr == nil { + println("fakecgo: malloc failed") + abort() + } + pthread_attr_init(attr) + pthread_attr_getstacksize(attr, &size) + // runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))` + // but this should be OK since we are taking the address of the first variable in this function. + g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096 + pthread_attr_destroy(attr) + free(unsafe.Pointer(attr)) +} diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/go_freebsd_arm64.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_freebsd_arm64.go new file mode 100644 index 000000000..1db518e3a --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_freebsd_arm64.go @@ -0,0 +1,96 @@ +// Copyright 2011 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 fakecgo + +import "unsafe" + +//go:nosplit +func _cgo_sys_thread_start(ts *ThreadStart) { + var attr pthread_attr_t + var ign, oset sigset_t + var p pthread_t + var size size_t + var err int + + //fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug + sigfillset(&ign) + pthread_sigmask(SIG_SETMASK, &ign, &oset) + + pthread_attr_init(&attr) + pthread_attr_getstacksize(&attr, &size) + // Leave stacklo=0 and set stackhi=size; mstart will do the rest. + ts.g.stackhi = uintptr(size) + + err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts) + + pthread_sigmask(SIG_SETMASK, &oset, nil) + + if err != 0 { + print("fakecgo: pthread_create failed: ") + println(err) + abort() + } +} + +// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function +// +//go:linkname x_threadentry_trampoline threadentry_trampoline +var x_threadentry_trampoline byte +var threadentry_trampolineABI0 = &x_threadentry_trampoline + +//go:nosplit +func threadentry(v unsafe.Pointer) unsafe.Pointer { + ts := *(*ThreadStart)(v) + free(v) + + setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g))) + + // faking funcs in go is a bit a... involved - but the following works :) + fn := uintptr(unsafe.Pointer(&ts.fn)) + (*(*func())(unsafe.Pointer(&fn)))() + + return nil +} + +// here we will store a pointer to the provided setg func +var setg_func uintptr + +// x_cgo_init(G *g, void (*setg)(void*)) (runtime/cgo/gcc_linux_amd64.c) +// This get's called during startup, adjusts stacklo, and provides a pointer to setg_gcc for us +// Additionally, if we set _cgo_init to non-null, go won't do it's own TLS setup +// This function can't be go:systemstack since go is not in a state where the systemcheck would work. +// +//go:nosplit +func x_cgo_init(g *G, setg uintptr) { + var size size_t + var attr *pthread_attr_t + + /* The memory sanitizer distributed with versions of clang + before 3.8 has a bug: if you call mmap before malloc, mmap + may return an address that is later overwritten by the msan + library. Avoid this problem by forcing a call to malloc + here, before we ever call malloc. + + This is only required for the memory sanitizer, so it's + unfortunate that we always run it. It should be possible + to remove this when we no longer care about versions of + clang before 3.8. The test for this is + misc/cgo/testsanitizers. + + GCC works hard to eliminate a seemingly unnecessary call to + malloc, so we actually use the memory we allocate. */ + + setg_func = setg + attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr))) + if attr == nil { + println("fakecgo: malloc failed") + abort() + } + pthread_attr_init(attr) + pthread_attr_getstacksize(attr, &size) + g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096 + pthread_attr_destroy(attr) + free(unsafe.Pointer(attr)) +} diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/go_libinit.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_libinit.go new file mode 100644 index 000000000..71da11281 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_libinit.go @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || linux + +package fakecgo + +import ( + "syscall" + "unsafe" +) + +var ( + pthread_g pthread_key_t + + runtime_init_cond = PTHREAD_COND_INITIALIZER + runtime_init_mu = PTHREAD_MUTEX_INITIALIZER + runtime_init_done int +) + +//go:nosplit +func x_cgo_notify_runtime_init_done() { + pthread_mutex_lock(&runtime_init_mu) + runtime_init_done = 1 + pthread_cond_broadcast(&runtime_init_cond) + pthread_mutex_unlock(&runtime_init_mu) +} + +// Store the g into a thread-specific value associated with the pthread key pthread_g. +// And pthread_key_destructor will dropm when the thread is exiting. +func x_cgo_bindm(g unsafe.Pointer) { + // We assume this will always succeed, otherwise, there might be extra M leaking, + // when a C thread exits after a cgo call. + // We only invoke this function once per thread in runtime.needAndBindM, + // and the next calls just reuse the bound m. + pthread_setspecific(pthread_g, g) +} + +// _cgo_try_pthread_create retries pthread_create if it fails with +// EAGAIN. +// +//go:nosplit +//go:norace +func _cgo_try_pthread_create(thread *pthread_t, attr *pthread_attr_t, pfn unsafe.Pointer, arg *ThreadStart) int { + var ts syscall.Timespec + // tries needs to be the same type as syscall.Timespec.Nsec + // but the fields are int32 on 32bit and int64 on 64bit. + // tries is assigned to syscall.Timespec.Nsec in order to match its type. + tries := ts.Nsec + var err int + + for tries = 0; tries < 20; tries++ { + err = int(pthread_create(thread, attr, pfn, unsafe.Pointer(arg))) + if err == 0 { + pthread_detach(*thread) + return 0 + } + if err != int(syscall.EAGAIN) { + return err + } + ts.Sec = 0 + ts.Nsec = (tries + 1) * 1000 * 1000 // Milliseconds. + nanosleep(&ts, nil) + } + return int(syscall.EAGAIN) +} diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_amd64.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_amd64.go new file mode 100644 index 000000000..9aa57ef66 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_amd64.go @@ -0,0 +1,93 @@ +// Copyright 2011 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 fakecgo + +import "unsafe" + +//go:nosplit +func _cgo_sys_thread_start(ts *ThreadStart) { + var attr pthread_attr_t + var ign, oset sigset_t + var p pthread_t + var size size_t + var err int + + //fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug + sigfillset(&ign) + pthread_sigmask(SIG_SETMASK, &ign, &oset) + + pthread_attr_init(&attr) + pthread_attr_getstacksize(&attr, &size) + // Leave stacklo=0 and set stackhi=size; mstart will do the rest. + ts.g.stackhi = uintptr(size) + + err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts) + + pthread_sigmask(SIG_SETMASK, &oset, nil) + + if err != 0 { + print("fakecgo: pthread_create failed: ") + println(err) + abort() + } +} + +// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function +// +//go:linkname x_threadentry_trampoline threadentry_trampoline +var x_threadentry_trampoline byte +var threadentry_trampolineABI0 = &x_threadentry_trampoline + +//go:nosplit +func threadentry(v unsafe.Pointer) unsafe.Pointer { + ts := *(*ThreadStart)(v) + free(v) + + setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g))) + + // faking funcs in go is a bit a... involved - but the following works :) + fn := uintptr(unsafe.Pointer(&ts.fn)) + (*(*func())(unsafe.Pointer(&fn)))() + + return nil +} + +// here we will store a pointer to the provided setg func +var setg_func uintptr + +//go:nosplit +func x_cgo_init(g *G, setg uintptr) { + var size size_t + var attr *pthread_attr_t + + /* The memory sanitizer distributed with versions of clang + before 3.8 has a bug: if you call mmap before malloc, mmap + may return an address that is later overwritten by the msan + library. Avoid this problem by forcing a call to malloc + here, before we ever call malloc. + + This is only required for the memory sanitizer, so it's + unfortunate that we always run it. It should be possible + to remove this when we no longer care about versions of + clang before 3.8. The test for this is + misc/cgo/testsanitizers. + + GCC works hard to eliminate a seemingly unnecessary call to + malloc, so we actually use the memory we allocate. */ + + setg_func = setg + attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr))) + if attr == nil { + println("fakecgo: malloc failed") + abort() + } + pthread_attr_init(attr) + pthread_attr_getstacksize(attr, &size) + // runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))` + // but this should be OK since we are taking the address of the first variable in this function. + g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096 + pthread_attr_destroy(attr) + free(unsafe.Pointer(attr)) +} diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_arm64.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_arm64.go new file mode 100644 index 000000000..1db518e3a --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_arm64.go @@ -0,0 +1,96 @@ +// Copyright 2011 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 fakecgo + +import "unsafe" + +//go:nosplit +func _cgo_sys_thread_start(ts *ThreadStart) { + var attr pthread_attr_t + var ign, oset sigset_t + var p pthread_t + var size size_t + var err int + + //fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug + sigfillset(&ign) + pthread_sigmask(SIG_SETMASK, &ign, &oset) + + pthread_attr_init(&attr) + pthread_attr_getstacksize(&attr, &size) + // Leave stacklo=0 and set stackhi=size; mstart will do the rest. + ts.g.stackhi = uintptr(size) + + err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts) + + pthread_sigmask(SIG_SETMASK, &oset, nil) + + if err != 0 { + print("fakecgo: pthread_create failed: ") + println(err) + abort() + } +} + +// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function +// +//go:linkname x_threadentry_trampoline threadentry_trampoline +var x_threadentry_trampoline byte +var threadentry_trampolineABI0 = &x_threadentry_trampoline + +//go:nosplit +func threadentry(v unsafe.Pointer) unsafe.Pointer { + ts := *(*ThreadStart)(v) + free(v) + + setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g))) + + // faking funcs in go is a bit a... involved - but the following works :) + fn := uintptr(unsafe.Pointer(&ts.fn)) + (*(*func())(unsafe.Pointer(&fn)))() + + return nil +} + +// here we will store a pointer to the provided setg func +var setg_func uintptr + +// x_cgo_init(G *g, void (*setg)(void*)) (runtime/cgo/gcc_linux_amd64.c) +// This get's called during startup, adjusts stacklo, and provides a pointer to setg_gcc for us +// Additionally, if we set _cgo_init to non-null, go won't do it's own TLS setup +// This function can't be go:systemstack since go is not in a state where the systemcheck would work. +// +//go:nosplit +func x_cgo_init(g *G, setg uintptr) { + var size size_t + var attr *pthread_attr_t + + /* The memory sanitizer distributed with versions of clang + before 3.8 has a bug: if you call mmap before malloc, mmap + may return an address that is later overwritten by the msan + library. Avoid this problem by forcing a call to malloc + here, before we ever call malloc. + + This is only required for the memory sanitizer, so it's + unfortunate that we always run it. It should be possible + to remove this when we no longer care about versions of + clang before 3.8. The test for this is + misc/cgo/testsanitizers. + + GCC works hard to eliminate a seemingly unnecessary call to + malloc, so we actually use the memory we allocate. */ + + setg_func = setg + attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr))) + if attr == nil { + println("fakecgo: malloc failed") + abort() + } + pthread_attr_init(attr) + pthread_attr_getstacksize(attr, &size) + g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096 + pthread_attr_destroy(attr) + free(unsafe.Pointer(attr)) +} diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/go_setenv.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_setenv.go new file mode 100644 index 000000000..818372ea0 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_setenv.go @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || linux + +package fakecgo + +//go:nosplit +//go:norace +func x_cgo_setenv(arg *[2]*byte) { + setenv(arg[0], arg[1], 1) +} + +//go:nosplit +//go:norace +func x_cgo_unsetenv(arg *[1]*byte) { + unsetenv(arg[0]) +} diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/go_util.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_util.go new file mode 100644 index 000000000..7a43b42b6 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/go_util.go @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || linux + +package fakecgo + +import "unsafe" + +// _cgo_thread_start is split into three parts in cgo since only one part is system dependent (keep it here for easier handling) + +// _cgo_thread_start(ThreadStart *arg) (runtime/cgo/gcc_util.c) +// This get's called instead of the go code for creating new threads +// -> pthread_* stuff is used, so threads are setup correctly for C +// If this is missing, TLS is only setup correctly on thread 1! +// This function should be go:systemstack instead of go:nosplit (but that requires runtime) +// +//go:nosplit +//go:norace +func x_cgo_thread_start(arg *ThreadStart) { + var ts *ThreadStart + // Make our own copy that can persist after we return. + // _cgo_tsan_acquire(); + ts = (*ThreadStart)(malloc(unsafe.Sizeof(*ts))) + // _cgo_tsan_release(); + if ts == nil { + println("fakecgo: out of memory in thread_start") + abort() + } + // *ts = *arg would cause a writebarrier so use memmove instead + memmove(unsafe.Pointer(ts), unsafe.Pointer(arg), unsafe.Sizeof(*ts)) + _cgo_sys_thread_start(ts) // OS-dependent half +} diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/iscgo.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/iscgo.go new file mode 100644 index 000000000..ce17d1828 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/iscgo.go @@ -0,0 +1,19 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build darwin || freebsd || linux + +// The runtime package contains an uninitialized definition +// for runtime·iscgo. Override it to tell the runtime we're here. +// There are various function pointers that should be set too, +// but those depend on dynamic linker magic to get initialized +// correctly, and sometimes they break. This variable is a +// backup: it depends only on old C style static linking rules. + +package fakecgo + +import _ "unsafe" // for go:linkname + +//go:linkname _iscgo runtime.iscgo +var _iscgo bool = true diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo.go new file mode 100644 index 000000000..c12d403c3 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo.go @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || linux + +package fakecgo + +type ( + size_t uintptr + sigset_t [128]byte + pthread_attr_t [64]byte + pthread_t int + pthread_key_t uint64 +) + +// for pthread_sigmask: + +type sighow int32 + +const ( + SIG_BLOCK sighow = 0 + SIG_UNBLOCK sighow = 1 + SIG_SETMASK sighow = 2 +) + +type G struct { + stacklo uintptr + stackhi uintptr +} + +type ThreadStart struct { + g *G + tls *uintptr + fn uintptr +} diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_darwin.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_darwin.go new file mode 100644 index 000000000..03c917183 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_darwin.go @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +package fakecgo + +type ( + pthread_mutex_t struct { + sig int64 + opaque [56]byte + } + pthread_cond_t struct { + sig int64 + opaque [40]byte + } +) + +var ( + PTHREAD_COND_INITIALIZER = pthread_cond_t{sig: 0x3CB0B1BB} + PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t{sig: 0x32AAABA7} +) diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_freebsd.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_freebsd.go new file mode 100644 index 000000000..baf03fa85 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_freebsd.go @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +package fakecgo + +type ( + pthread_cond_t uintptr + pthread_mutex_t uintptr +) + +var ( + PTHREAD_COND_INITIALIZER = pthread_cond_t(0) + PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t(0) +) diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_linux.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_linux.go new file mode 100644 index 000000000..93aa5b26e --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_linux.go @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +package fakecgo + +type ( + pthread_cond_t [48]byte + pthread_mutex_t [48]byte +) + +var ( + PTHREAD_COND_INITIALIZER = pthread_cond_t{} + PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t{} +) diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/setenv.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/setenv.go new file mode 100644 index 000000000..b69d4b39f --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/setenv.go @@ -0,0 +1,19 @@ +// Copyright 2011 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 darwin || freebsd || linux + +package fakecgo + +import _ "unsafe" // for go:linkname + +//go:linkname x_cgo_setenv_trampoline x_cgo_setenv_trampoline +//go:linkname _cgo_setenv runtime._cgo_setenv +var x_cgo_setenv_trampoline byte +var _cgo_setenv = &x_cgo_setenv_trampoline + +//go:linkname x_cgo_unsetenv_trampoline x_cgo_unsetenv_trampoline +//go:linkname _cgo_unsetenv runtime._cgo_unsetenv +var x_cgo_unsetenv_trampoline byte +var _cgo_unsetenv = &x_cgo_unsetenv_trampoline diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols.go new file mode 100644 index 000000000..d7401f705 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols.go @@ -0,0 +1,184 @@ +// Code generated by 'go generate' with gen.go. DO NOT EDIT. + +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || linux + +package fakecgo + +import ( + "syscall" + "unsafe" +) + +// setg_trampoline calls setg with the G provided +func setg_trampoline(setg uintptr, G uintptr) + +//go:linkname memmove runtime.memmove +func memmove(to, from unsafe.Pointer, n uintptr) + +// call5 takes fn the C function and 5 arguments and calls the function with those arguments +func call5(fn, a1, a2, a3, a4, a5 uintptr) uintptr + +func malloc(size uintptr) unsafe.Pointer { + ret := call5(mallocABI0, uintptr(size), 0, 0, 0, 0) + // this indirection is to avoid go vet complaining about possible misuse of unsafe.Pointer + return *(*unsafe.Pointer)(unsafe.Pointer(&ret)) +} + +func free(ptr unsafe.Pointer) { + call5(freeABI0, uintptr(ptr), 0, 0, 0, 0) +} + +func setenv(name *byte, value *byte, overwrite int32) int32 { + return int32(call5(setenvABI0, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), uintptr(overwrite), 0, 0)) +} + +func unsetenv(name *byte) int32 { + return int32(call5(unsetenvABI0, uintptr(unsafe.Pointer(name)), 0, 0, 0, 0)) +} + +func sigfillset(set *sigset_t) int32 { + return int32(call5(sigfillsetABI0, uintptr(unsafe.Pointer(set)), 0, 0, 0, 0)) +} + +func nanosleep(ts *syscall.Timespec, rem *syscall.Timespec) int32 { + return int32(call5(nanosleepABI0, uintptr(unsafe.Pointer(ts)), uintptr(unsafe.Pointer(rem)), 0, 0, 0)) +} + +func abort() { + call5(abortABI0, 0, 0, 0, 0, 0) +} + +func pthread_attr_init(attr *pthread_attr_t) int32 { + return int32(call5(pthread_attr_initABI0, uintptr(unsafe.Pointer(attr)), 0, 0, 0, 0)) +} + +func pthread_create(thread *pthread_t, attr *pthread_attr_t, start unsafe.Pointer, arg unsafe.Pointer) int32 { + return int32(call5(pthread_createABI0, uintptr(unsafe.Pointer(thread)), uintptr(unsafe.Pointer(attr)), uintptr(start), uintptr(arg), 0)) +} + +func pthread_detach(thread pthread_t) int32 { + return int32(call5(pthread_detachABI0, uintptr(thread), 0, 0, 0, 0)) +} + +func pthread_sigmask(how sighow, ign *sigset_t, oset *sigset_t) int32 { + return int32(call5(pthread_sigmaskABI0, uintptr(how), uintptr(unsafe.Pointer(ign)), uintptr(unsafe.Pointer(oset)), 0, 0)) +} + +func pthread_self() pthread_t { + return pthread_t(call5(pthread_selfABI0, 0, 0, 0, 0, 0)) +} + +func pthread_get_stacksize_np(thread pthread_t) size_t { + return size_t(call5(pthread_get_stacksize_npABI0, uintptr(thread), 0, 0, 0, 0)) +} + +func pthread_attr_getstacksize(attr *pthread_attr_t, stacksize *size_t) int32 { + return int32(call5(pthread_attr_getstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(stacksize)), 0, 0, 0)) +} + +func pthread_attr_setstacksize(attr *pthread_attr_t, size size_t) int32 { + return int32(call5(pthread_attr_setstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(size), 0, 0, 0)) +} + +func pthread_attr_destroy(attr *pthread_attr_t) int32 { + return int32(call5(pthread_attr_destroyABI0, uintptr(unsafe.Pointer(attr)), 0, 0, 0, 0)) +} + +func pthread_mutex_lock(mutex *pthread_mutex_t) int32 { + return int32(call5(pthread_mutex_lockABI0, uintptr(unsafe.Pointer(mutex)), 0, 0, 0, 0)) +} + +func pthread_mutex_unlock(mutex *pthread_mutex_t) int32 { + return int32(call5(pthread_mutex_unlockABI0, uintptr(unsafe.Pointer(mutex)), 0, 0, 0, 0)) +} + +func pthread_cond_broadcast(cond *pthread_cond_t) int32 { + return int32(call5(pthread_cond_broadcastABI0, uintptr(unsafe.Pointer(cond)), 0, 0, 0, 0)) +} + +func pthread_setspecific(key pthread_key_t, value unsafe.Pointer) int32 { + return int32(call5(pthread_setspecificABI0, uintptr(key), uintptr(value), 0, 0, 0)) +} + +//go:linkname _malloc _malloc +var _malloc uintptr +var mallocABI0 = uintptr(unsafe.Pointer(&_malloc)) + +//go:linkname _free _free +var _free uintptr +var freeABI0 = uintptr(unsafe.Pointer(&_free)) + +//go:linkname _setenv _setenv +var _setenv uintptr +var setenvABI0 = uintptr(unsafe.Pointer(&_setenv)) + +//go:linkname _unsetenv _unsetenv +var _unsetenv uintptr +var unsetenvABI0 = uintptr(unsafe.Pointer(&_unsetenv)) + +//go:linkname _sigfillset _sigfillset +var _sigfillset uintptr +var sigfillsetABI0 = uintptr(unsafe.Pointer(&_sigfillset)) + +//go:linkname _nanosleep _nanosleep +var _nanosleep uintptr +var nanosleepABI0 = uintptr(unsafe.Pointer(&_nanosleep)) + +//go:linkname _abort _abort +var _abort uintptr +var abortABI0 = uintptr(unsafe.Pointer(&_abort)) + +//go:linkname _pthread_attr_init _pthread_attr_init +var _pthread_attr_init uintptr +var pthread_attr_initABI0 = uintptr(unsafe.Pointer(&_pthread_attr_init)) + +//go:linkname _pthread_create _pthread_create +var _pthread_create uintptr +var pthread_createABI0 = uintptr(unsafe.Pointer(&_pthread_create)) + +//go:linkname _pthread_detach _pthread_detach +var _pthread_detach uintptr +var pthread_detachABI0 = uintptr(unsafe.Pointer(&_pthread_detach)) + +//go:linkname _pthread_sigmask _pthread_sigmask +var _pthread_sigmask uintptr +var pthread_sigmaskABI0 = uintptr(unsafe.Pointer(&_pthread_sigmask)) + +//go:linkname _pthread_self _pthread_self +var _pthread_self uintptr +var pthread_selfABI0 = uintptr(unsafe.Pointer(&_pthread_self)) + +//go:linkname _pthread_get_stacksize_np _pthread_get_stacksize_np +var _pthread_get_stacksize_np uintptr +var pthread_get_stacksize_npABI0 = uintptr(unsafe.Pointer(&_pthread_get_stacksize_np)) + +//go:linkname _pthread_attr_getstacksize _pthread_attr_getstacksize +var _pthread_attr_getstacksize uintptr +var pthread_attr_getstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_getstacksize)) + +//go:linkname _pthread_attr_setstacksize _pthread_attr_setstacksize +var _pthread_attr_setstacksize uintptr +var pthread_attr_setstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_setstacksize)) + +//go:linkname _pthread_attr_destroy _pthread_attr_destroy +var _pthread_attr_destroy uintptr +var pthread_attr_destroyABI0 = uintptr(unsafe.Pointer(&_pthread_attr_destroy)) + +//go:linkname _pthread_mutex_lock _pthread_mutex_lock +var _pthread_mutex_lock uintptr +var pthread_mutex_lockABI0 = uintptr(unsafe.Pointer(&_pthread_mutex_lock)) + +//go:linkname _pthread_mutex_unlock _pthread_mutex_unlock +var _pthread_mutex_unlock uintptr +var pthread_mutex_unlockABI0 = uintptr(unsafe.Pointer(&_pthread_mutex_unlock)) + +//go:linkname _pthread_cond_broadcast _pthread_cond_broadcast +var _pthread_cond_broadcast uintptr +var pthread_cond_broadcastABI0 = uintptr(unsafe.Pointer(&_pthread_cond_broadcast)) + +//go:linkname _pthread_setspecific _pthread_setspecific +var _pthread_setspecific uintptr +var pthread_setspecificABI0 = uintptr(unsafe.Pointer(&_pthread_setspecific)) diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_darwin.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_darwin.go new file mode 100644 index 000000000..7341fecd4 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_darwin.go @@ -0,0 +1,27 @@ +// Code generated by 'go generate' with gen.go. DO NOT EDIT. + +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +package fakecgo + +//go:cgo_import_dynamic purego_malloc malloc "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_free free "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_setenv setenv "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_unsetenv unsetenv "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_sigfillset sigfillset "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_nanosleep nanosleep "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_abort abort "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_pthread_create pthread_create "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_pthread_detach pthread_detach "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_pthread_self pthread_self "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_pthread_get_stacksize_np pthread_get_stacksize_np "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_pthread_attr_setstacksize pthread_attr_setstacksize "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "/usr/lib/libSystem.B.dylib" diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_freebsd.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_freebsd.go new file mode 100644 index 000000000..bff096d51 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_freebsd.go @@ -0,0 +1,27 @@ +// Code generated by 'go generate' with gen.go. DO NOT EDIT. + +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +package fakecgo + +//go:cgo_import_dynamic purego_malloc malloc "libc.so.7" +//go:cgo_import_dynamic purego_free free "libc.so.7" +//go:cgo_import_dynamic purego_setenv setenv "libc.so.7" +//go:cgo_import_dynamic purego_unsetenv unsetenv "libc.so.7" +//go:cgo_import_dynamic purego_sigfillset sigfillset "libc.so.7" +//go:cgo_import_dynamic purego_nanosleep nanosleep "libc.so.7" +//go:cgo_import_dynamic purego_abort abort "libc.so.7" +//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "libpthread.so" +//go:cgo_import_dynamic purego_pthread_create pthread_create "libpthread.so" +//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libpthread.so" +//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libpthread.so" +//go:cgo_import_dynamic purego_pthread_self pthread_self "libpthread.so" +//go:cgo_import_dynamic purego_pthread_get_stacksize_np pthread_get_stacksize_np "libpthread.so" +//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so" +//go:cgo_import_dynamic purego_pthread_attr_setstacksize pthread_attr_setstacksize "libpthread.so" +//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so" +//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libpthread.so" +//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libpthread.so" +//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libpthread.so" +//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libpthread.so" diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_linux.go b/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_linux.go new file mode 100644 index 000000000..ee3ab7aaf --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_linux.go @@ -0,0 +1,27 @@ +// Code generated by 'go generate' with gen.go. DO NOT EDIT. + +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +package fakecgo + +//go:cgo_import_dynamic purego_malloc malloc "libc.so.6" +//go:cgo_import_dynamic purego_free free "libc.so.6" +//go:cgo_import_dynamic purego_setenv setenv "libc.so.6" +//go:cgo_import_dynamic purego_unsetenv unsetenv "libc.so.6" +//go:cgo_import_dynamic purego_sigfillset sigfillset "libc.so.6" +//go:cgo_import_dynamic purego_nanosleep nanosleep "libc.so.6" +//go:cgo_import_dynamic purego_abort abort "libc.so.6" +//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "libpthread.so.0" +//go:cgo_import_dynamic purego_pthread_create pthread_create "libpthread.so.0" +//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libpthread.so.0" +//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libpthread.so.0" +//go:cgo_import_dynamic purego_pthread_self pthread_self "libpthread.so.0" +//go:cgo_import_dynamic purego_pthread_get_stacksize_np pthread_get_stacksize_np "libpthread.so.0" +//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so.0" +//go:cgo_import_dynamic purego_pthread_attr_setstacksize pthread_attr_setstacksize "libpthread.so.0" +//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so.0" +//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libpthread.so.0" +//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libpthread.so.0" +//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libpthread.so.0" +//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libpthread.so.0" diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_amd64.s b/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_amd64.s new file mode 100644 index 000000000..24b620606 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_amd64.s @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || linux || freebsd + +/* +trampoline for emulating required C functions for cgo in go (see cgo.go) +(we convert cdecl calling convention to go and vice-versa) + +Since we're called from go and call into C we can cheat a bit with the calling conventions: + - in go all the registers are caller saved + - in C we have a couple of callee saved registers + +=> we can use BX, R12, R13, R14, R15 instead of the stack + +C Calling convention cdecl used here (we only need integer args): +1. arg: DI +2. arg: SI +3. arg: DX +4. arg: CX +5. arg: R8 +6. arg: R9 +We don't need floats with these functions -> AX=0 +return value will be in AX +*/ +#include "textflag.h" +#include "go_asm.h" + +// these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions. + +TEXT x_cgo_init_trampoline(SB), NOSPLIT, $16 + MOVQ DI, AX + MOVQ SI, BX + MOVQ ·x_cgo_init_call(SB), DX + MOVQ (DX), CX + CALL CX + RET + +TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $8 + MOVQ DI, AX + MOVQ ·x_cgo_thread_start_call(SB), DX + MOVQ (DX), CX + CALL CX + RET + +TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $8 + MOVQ DI, AX + MOVQ ·x_cgo_setenv_call(SB), DX + MOVQ (DX), CX + CALL CX + RET + +TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $8 + MOVQ DI, AX + MOVQ ·x_cgo_unsetenv_call(SB), DX + MOVQ (DX), CX + CALL CX + RET + +TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0 + CALL ·x_cgo_notify_runtime_init_done(SB) + RET + +TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0 + CALL ·x_cgo_bindm(SB) + RET + +// func setg_trampoline(setg uintptr, g uintptr) +TEXT ·setg_trampoline(SB), NOSPLIT, $0-16 + MOVQ G+8(FP), DI + MOVQ setg+0(FP), BX + XORL AX, AX + CALL BX + RET + +TEXT threadentry_trampoline(SB), NOSPLIT, $16 + MOVQ DI, AX + MOVQ ·threadentry_call(SB), DX + MOVQ (DX), CX + CALL CX + RET + +TEXT ·call5(SB), NOSPLIT, $0-56 + MOVQ fn+0(FP), BX + MOVQ a1+8(FP), DI + MOVQ a2+16(FP), SI + MOVQ a3+24(FP), DX + MOVQ a4+32(FP), CX + MOVQ a5+40(FP), R8 + + XORL AX, AX // no floats + + PUSHQ BP // save BP + MOVQ SP, BP // save SP inside BP bc BP is callee-saved + SUBQ $16, SP // allocate space for alignment + ANDQ $-16, SP // align on 16 bytes for SSE + + CALL BX + + MOVQ BP, SP // get SP back + POPQ BP // restore BP + + MOVQ AX, ret+48(FP) + RET diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_arm64.s b/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_arm64.s new file mode 100644 index 000000000..9c80fe2f6 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_arm64.s @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || linux + +#include "textflag.h" +#include "go_asm.h" + +// these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions. + +TEXT x_cgo_init_trampoline(SB), NOSPLIT, $0-0 + MOVD R0, 8(RSP) + MOVD R1, 16(RSP) + MOVD ·x_cgo_init_call(SB), R26 + MOVD (R26), R2 + CALL (R2) + RET + +TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $0-0 + MOVD R0, 8(RSP) + MOVD ·x_cgo_thread_start_call(SB), R26 + MOVD (R26), R2 + CALL (R2) + RET + +TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $0-0 + MOVD R0, 8(RSP) + MOVD ·x_cgo_setenv_call(SB), R26 + MOVD (R26), R2 + CALL (R2) + RET + +TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $0-0 + MOVD R0, 8(RSP) + MOVD ·x_cgo_unsetenv_call(SB), R26 + MOVD (R26), R2 + CALL (R2) + RET + +TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0-0 + CALL ·x_cgo_notify_runtime_init_done(SB) + RET + +TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0 + CALL ·x_cgo_bindm(SB) + RET + +// func setg_trampoline(setg uintptr, g uintptr) +TEXT ·setg_trampoline(SB), NOSPLIT, $0-16 + MOVD G+8(FP), R0 + MOVD setg+0(FP), R1 + CALL R1 + RET + +TEXT threadentry_trampoline(SB), NOSPLIT, $0-0 + MOVD R0, 8(RSP) + MOVD ·threadentry_call(SB), R26 + MOVD (R26), R2 + CALL (R2) + MOVD $0, R0 // TODO: get the return value from threadentry + RET + +TEXT ·call5(SB), NOSPLIT, $0-0 + MOVD fn+0(FP), R6 + MOVD a1+8(FP), R0 + MOVD a2+16(FP), R1 + MOVD a3+24(FP), R2 + MOVD a4+32(FP), R3 + MOVD a5+40(FP), R4 + CALL R6 + MOVD R0, ret+48(FP) + RET diff --git a/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_stubs.s b/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_stubs.s new file mode 100644 index 000000000..e8726376d --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_stubs.s @@ -0,0 +1,90 @@ +// Code generated by 'go generate' with gen.go. DO NOT EDIT. + +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || linux + +#include "textflag.h" + +// these stubs are here because it is not possible to go:linkname directly the C functions on darwin arm64 + +TEXT _malloc(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_malloc(SB) + RET + +TEXT _free(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_free(SB) + RET + +TEXT _setenv(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_setenv(SB) + RET + +TEXT _unsetenv(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_unsetenv(SB) + RET + +TEXT _sigfillset(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_sigfillset(SB) + RET + +TEXT _nanosleep(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_nanosleep(SB) + RET + +TEXT _abort(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_abort(SB) + RET + +TEXT _pthread_attr_init(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_pthread_attr_init(SB) + RET + +TEXT _pthread_create(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_pthread_create(SB) + RET + +TEXT _pthread_detach(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_pthread_detach(SB) + RET + +TEXT _pthread_sigmask(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_pthread_sigmask(SB) + RET + +TEXT _pthread_self(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_pthread_self(SB) + RET + +TEXT _pthread_get_stacksize_np(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_pthread_get_stacksize_np(SB) + RET + +TEXT _pthread_attr_getstacksize(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_pthread_attr_getstacksize(SB) + RET + +TEXT _pthread_attr_setstacksize(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_pthread_attr_setstacksize(SB) + RET + +TEXT _pthread_attr_destroy(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_pthread_attr_destroy(SB) + RET + +TEXT _pthread_mutex_lock(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_pthread_mutex_lock(SB) + RET + +TEXT _pthread_mutex_unlock(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_pthread_mutex_unlock(SB) + RET + +TEXT _pthread_cond_broadcast(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_pthread_cond_broadcast(SB) + RET + +TEXT _pthread_setspecific(SB), NOSPLIT|NOFRAME, $0-0 + JMP purego_pthread_setspecific(SB) + RET diff --git a/vendor/github.com/ebitengine/purego/internal/strings/strings.go b/vendor/github.com/ebitengine/purego/internal/strings/strings.go new file mode 100644 index 000000000..5b0d25225 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/internal/strings/strings.go @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +package strings + +import ( + "unsafe" +) + +// hasSuffix tests whether the string s ends with suffix. +func hasSuffix(s, suffix string) bool { + return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix +} + +// CString converts a go string to *byte that can be passed to C code. +func CString(name string) *byte { + if hasSuffix(name, "\x00") { + return &(*(*[]byte)(unsafe.Pointer(&name)))[0] + } + b := make([]byte, len(name)+1) + copy(b, name) + return &b[0] +} + +// GoString copies a null-terminated char* to a Go string. +func GoString(c uintptr) string { + // We take the address and then dereference it to trick go vet from creating a possible misuse of unsafe.Pointer + ptr := *(*unsafe.Pointer)(unsafe.Pointer(&c)) + if ptr == nil { + return "" + } + var length int + for { + if *(*byte)(unsafe.Add(ptr, uintptr(length))) == '\x00' { + break + } + length++ + } + return string(unsafe.Slice((*byte)(ptr), length)) +} diff --git a/vendor/github.com/ebitengine/purego/is_ios.go b/vendor/github.com/ebitengine/purego/is_ios.go new file mode 100644 index 000000000..ed31da978 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/is_ios.go @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build !cgo + +package purego + +// if you are getting this error it means that you have +// CGO_ENABLED=0 while trying to build for ios. +// purego does not support this mode yet. +// the fix is to set CGO_ENABLED=1 which will require +// a C compiler. +var _ = _PUREGO_REQUIRES_CGO_ON_IOS diff --git a/vendor/github.com/ebitengine/purego/nocgo.go b/vendor/github.com/ebitengine/purego/nocgo.go new file mode 100644 index 000000000..5b989ea81 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/nocgo.go @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build !cgo && (darwin || freebsd || linux) + +package purego + +// if CGO_ENABLED=0 import fakecgo to setup the Cgo runtime correctly. +// This is required since some frameworks need TLS setup the C way which Go doesn't do. +// We currently don't support ios in fakecgo mode so force Cgo or fail +// +// The way that the Cgo runtime (runtime/cgo) works is by setting some variables found +// in runtime with non-null GCC compiled functions. The variables that are replaced are +// var ( +// iscgo bool // in runtime/cgo.go +// _cgo_init unsafe.Pointer // in runtime/cgo.go +// _cgo_thread_start unsafe.Pointer // in runtime/cgo.go +// _cgo_notify_runtime_init_done unsafe.Pointer // in runtime/cgo.go +// _cgo_setenv unsafe.Pointer // in runtime/env_posix.go +// _cgo_unsetenv unsafe.Pointer // in runtime/env_posix.go +// ) +// importing fakecgo will set these (using //go:linkname) with functions written +// entirely in Go (except for some assembly trampolines to change GCC ABI to Go ABI). +// Doing so makes it possible to build applications that call into C without CGO_ENABLED=1. +import _ "github.com/ebitengine/purego/internal/fakecgo" diff --git a/vendor/github.com/ebitengine/purego/sys_amd64.s b/vendor/github.com/ebitengine/purego/sys_amd64.s new file mode 100644 index 000000000..6daa298df --- /dev/null +++ b/vendor/github.com/ebitengine/purego/sys_amd64.s @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || (!cgo && linux) + +#include "textflag.h" +#include "abi_amd64.h" +#include "go_asm.h" +#include "funcdata.h" + +// syscall9X calls a function in libc on behalf of the syscall package. +// syscall9X takes a pointer to a struct like: +// struct { +// fn uintptr +// a1 uintptr +// a2 uintptr +// a3 uintptr +// a4 uintptr +// a5 uintptr +// a6 uintptr +// a7 uintptr +// a8 uintptr +// a9 uintptr +// r1 uintptr +// r2 uintptr +// err uintptr +// } +// syscall9X must be called on the g0 stack with the +// C calling convention (use libcCall). +GLOBL ·syscall9XABI0(SB), NOPTR|RODATA, $8 +DATA ·syscall9XABI0(SB)/8, $syscall9X(SB) +TEXT syscall9X(SB), NOSPLIT|NOFRAME, $0 + PUSHQ BP + MOVQ SP, BP + SUBQ $32, SP + MOVQ DI, 24(BP) // save the pointer + + MOVQ syscall9Args_f1(DI), X0 // f1 + MOVQ syscall9Args_f2(DI), X1 // f2 + MOVQ syscall9Args_f3(DI), X2 // f3 + MOVQ syscall9Args_f4(DI), X3 // f4 + MOVQ syscall9Args_f5(DI), X4 // f5 + MOVQ syscall9Args_f6(DI), X5 // f6 + MOVQ syscall9Args_f7(DI), X6 // f7 + MOVQ syscall9Args_f8(DI), X7 // f8 + + MOVQ syscall9Args_fn(DI), R10 // fn + MOVQ syscall9Args_a2(DI), SI // a2 + MOVQ syscall9Args_a3(DI), DX // a3 + MOVQ syscall9Args_a4(DI), CX // a4 + MOVQ syscall9Args_a5(DI), R8 // a5 + MOVQ syscall9Args_a6(DI), R9 // a6 + MOVQ syscall9Args_a7(DI), R11 // a7 + MOVQ syscall9Args_a8(DI), R12 // a8 + MOVQ syscall9Args_a9(DI), R13 // a9 + MOVQ syscall9Args_a1(DI), DI // a1 + + // push the remaining paramters onto the stack + MOVQ R11, 0(SP) // push a7 + MOVQ R12, 8(SP) // push a8 + MOVQ R13, 16(SP) // push a9 + XORL AX, AX // vararg: say "no float args" + + CALL R10 + + MOVQ 24(BP), DI // get the pointer back + MOVQ AX, syscall9Args_r1(DI) // r1 + MOVQ X0, syscall9Args_r2(DI) // r2 + + XORL AX, AX // no error (it's ignored anyway) + ADDQ $32, SP + MOVQ BP, SP + POPQ BP + RET + +TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0 + // remove return address from stack, we are not returning to callbackasm, but to its caller. + MOVQ 0(SP), AX + ADDQ $8, SP + + MOVQ 0(SP), R10 // get the return SP so that we can align register args with stack args + + // make space for first six int and 8 float arguments below the frame + ADJSP $14*8, SP + MOVSD X0, (1*8)(SP) + MOVSD X1, (2*8)(SP) + MOVSD X2, (3*8)(SP) + MOVSD X3, (4*8)(SP) + MOVSD X4, (5*8)(SP) + MOVSD X5, (6*8)(SP) + MOVSD X6, (7*8)(SP) + MOVSD X7, (8*8)(SP) + MOVQ DI, (9*8)(SP) + MOVQ SI, (10*8)(SP) + MOVQ DX, (11*8)(SP) + MOVQ CX, (12*8)(SP) + MOVQ R8, (13*8)(SP) + MOVQ R9, (14*8)(SP) + LEAQ 8(SP), R8 // R8 = address of args vector + + MOVQ R10, 0(SP) // push the stack pointer below registers + + // determine index into runtime·cbs table + MOVQ $callbackasm(SB), DX + SUBQ DX, AX + MOVQ $0, DX + MOVQ $5, CX // divide by 5 because each call instruction in ·callbacks is 5 bytes long + DIVL CX + SUBQ $1, AX // subtract 1 because return PC is to the next slot + + // Switch from the host ABI to the Go ABI. + PUSH_REGS_HOST_TO_ABI0() + + // Create a struct callbackArgs on our stack to be passed as + // the "frame" to cgocallback and on to callbackWrap. + // $24 to make enough room for the arguments to runtime.cgocallback + SUBQ $(24+callbackArgs__size), SP + MOVQ AX, (24+callbackArgs_index)(SP) // callback index + MOVQ R8, (24+callbackArgs_args)(SP) // address of args vector + MOVQ $0, (24+callbackArgs_result)(SP) // result + LEAQ 24(SP), AX // take the address of callbackArgs + + // Call cgocallback, which will call callbackWrap(frame). + MOVQ ·callbackWrap_call(SB), DI // Get the ABIInternal function pointer + MOVQ (DI), DI // without by using a closure. + MOVQ AX, SI // frame (address of callbackArgs) + MOVQ $0, CX // context + + CALL crosscall2(SB) // runtime.cgocallback(fn, frame, ctxt uintptr) + + // Get callback result. + MOVQ (24+callbackArgs_result)(SP), AX + ADDQ $(24+callbackArgs__size), SP // remove callbackArgs struct + + POP_REGS_HOST_TO_ABI0() + + MOVQ 0(SP), R10 // get the SP back + + ADJSP $-14*8, SP // remove arguments + + MOVQ R10, 0(SP) + + RET diff --git a/vendor/github.com/ebitengine/purego/sys_arm64.s b/vendor/github.com/ebitengine/purego/sys_arm64.s new file mode 100644 index 000000000..914ebb4e9 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/sys_arm64.s @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || (!cgo && linux) || windows + +#include "textflag.h" +#include "go_asm.h" +#include "funcdata.h" + +// syscall9X calls a function in libc on behalf of the syscall package. +// syscall9X takes a pointer to a struct like: +// struct { +// fn uintptr +// a1 uintptr +// a2 uintptr +// a3 uintptr +// a4 uintptr +// a5 uintptr +// a6 uintptr +// a7 uintptr +// a8 uintptr +// a9 uintptr +// r1 uintptr +// r2 uintptr +// err uintptr +// } +// syscall9X must be called on the g0 stack with the +// C calling convention (use libcCall). +GLOBL ·syscall9XABI0(SB), NOPTR|RODATA, $8 +DATA ·syscall9XABI0(SB)/8, $syscall9X(SB) +TEXT syscall9X(SB), NOSPLIT, $0 + SUB $16, RSP // push structure pointer + MOVD R0, 8(RSP) + + FMOVD syscall9Args_f1(R0), F0 // f1 + FMOVD syscall9Args_f2(R0), F1 // f2 + FMOVD syscall9Args_f3(R0), F2 // f3 + FMOVD syscall9Args_f4(R0), F3 // f4 + FMOVD syscall9Args_f5(R0), F4 // f5 + FMOVD syscall9Args_f6(R0), F5 // f6 + FMOVD syscall9Args_f7(R0), F6 // f7 + FMOVD syscall9Args_f8(R0), F7 // f8 + + MOVD syscall9Args_fn(R0), R12 // fn + MOVD syscall9Args_a2(R0), R1 // a2 + MOVD syscall9Args_a3(R0), R2 // a3 + MOVD syscall9Args_a4(R0), R3 // a4 + MOVD syscall9Args_a5(R0), R4 // a5 + MOVD syscall9Args_a6(R0), R5 // a6 + MOVD syscall9Args_a7(R0), R6 // a7 + MOVD syscall9Args_a8(R0), R7 // a8 + MOVD syscall9Args_a9(R0), R8 // a9 + MOVD syscall9Args_a1(R0), R0 // a1 + + MOVD R8, (RSP) // push a9 onto stack + + BL (R12) + + MOVD 8(RSP), R2 // pop structure pointer + ADD $16, RSP + MOVD R0, syscall9Args_r1(R2) // save r1 + FMOVD F0, syscall9Args_r2(R2) // save r2 + RET diff --git a/vendor/github.com/ebitengine/purego/sys_unix_arm64.s b/vendor/github.com/ebitengine/purego/sys_unix_arm64.s new file mode 100644 index 000000000..c1552d349 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/sys_unix_arm64.s @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 The Ebitengine Authors + +//go:build darwin || freebsd || (!cgo && linux) + +#include "textflag.h" +#include "go_asm.h" +#include "funcdata.h" +#include "abi_arm64.h" + +TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0 + NO_LOCAL_POINTERS + + // On entry, the trampoline in zcallback_darwin_arm64.s left + // the callback index in R12 (which is volatile in the C ABI). + + // Save callback register arguments R0-R7 and F0-F7. + // We do this at the top of the frame so they're contiguous with stack arguments. + SUB $(16*8), RSP, R14 + FSTPD (F0, F1), (0*8)(R14) + FSTPD (F2, F3), (2*8)(R14) + FSTPD (F4, F5), (4*8)(R14) + FSTPD (F6, F7), (6*8)(R14) + STP (R0, R1), (8*8)(R14) + STP (R2, R3), (10*8)(R14) + STP (R4, R5), (12*8)(R14) + STP (R6, R7), (14*8)(R14) + + // Adjust SP by frame size. + SUB $(26*8), RSP + + // It is important to save R27 because the go assembler + // uses it for move instructions for a variable. + // This line: + // MOVD ·callbackWrap_call(SB), R0 + // Creates the instructions: + // ADRP 14335(PC), R27 + // MOVD 388(27), R0 + // R27 is a callee saved register so we are responsible + // for ensuring its value doesn't change. So save it and + // restore it at the end of this function. + // R30 is the link register. crosscall2 doesn't save it + // so it's saved here. + STP (R27, R30), 0(RSP) + + // Create a struct callbackArgs on our stack. + MOVD $(callbackArgs__size)(RSP), R13 + MOVD R12, callbackArgs_index(R13) // callback index + MOVD R14, callbackArgs_args(R13) // address of args vector + MOVD ZR, callbackArgs_result(R13) // result + + // Move parameters into registers + // Get the ABIInternal function pointer + // without by using a closure. + MOVD ·callbackWrap_call(SB), R0 + MOVD (R0), R0 // fn unsafe.Pointer + MOVD R13, R1 // frame (&callbackArgs{...}) + MOVD $0, R3 // ctxt uintptr + + BL crosscall2(SB) + + // Get callback result. + MOVD $(callbackArgs__size)(RSP), R13 + MOVD callbackArgs_result(R13), R0 + + // Restore LR and R27 + LDP 0(RSP), (R27, R30) + ADD $(26*8), RSP + + RET diff --git a/vendor/github.com/ebitengine/purego/syscall.go b/vendor/github.com/ebitengine/purego/syscall.go new file mode 100644 index 000000000..44176be2a --- /dev/null +++ b/vendor/github.com/ebitengine/purego/syscall.go @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || linux || windows + +package purego + +const ( + maxArgs = 9 + numOfFloats = 8 // arm64 and amd64 both have 8 float registers +) + +// SyscallN takes fn, a C function pointer and a list of arguments as uintptr. +// There is an internal maximum number of arguments that SyscallN can take. It panics +// when the maximum is exceeded. It returns the result and the libc error code if there is one. +// +// NOTE: SyscallN does not properly call functions that have both integer and float parameters. +// See discussion comment https://github.com/ebiten/purego/pull/1#issuecomment-1128057607 +// for an explanation of why that is. +// +// On amd64, if there are more than 8 floats the 9th and so on will be placed incorrectly on the +// stack. +// +// The pragma go:nosplit is not needed at this function declaration because it uses go:uintptrescapes +// which forces all the objects that the uintptrs point to onto the heap where a stack split won't affect +// their memory location. +// +//go:uintptrescapes +func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { + if fn == 0 { + panic("purego: fn is nil") + } + if len(args) > maxArgs { + panic("purego: too many arguments to SyscallN") + } + // add padding so there is no out-of-bounds slicing + var tmp [maxArgs]uintptr + copy(tmp[:], args) + return syscall_syscall9X(fn, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8]) +} diff --git a/vendor/github.com/ebitengine/purego/syscall_cgo_linux.go b/vendor/github.com/ebitengine/purego/syscall_cgo_linux.go new file mode 100644 index 000000000..59c9a00bb --- /dev/null +++ b/vendor/github.com/ebitengine/purego/syscall_cgo_linux.go @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build cgo + +package purego + +import ( + _ "unsafe" // for go:linkname + + "github.com/ebitengine/purego/internal/cgo" +) + +var syscall9XABI0 = uintptr(cgo.Syscall9XABI0) + +// this is only here to make the assembly files happy :) +type syscall9Args struct { + fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr + f1, f2, f3, f4, f5, f6, f7, f8 uintptr + r1, r2, err uintptr +} + +//go:nosplit +func syscall_syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) { + return cgo.Syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9) +} + +func NewCallback(_ interface{}) uintptr { + panic("purego: NewCallback not supported") +} diff --git a/vendor/github.com/ebitengine/purego/syscall_sysv.go b/vendor/github.com/ebitengine/purego/syscall_sysv.go new file mode 100644 index 000000000..2d295cb0e --- /dev/null +++ b/vendor/github.com/ebitengine/purego/syscall_sysv.go @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +//go:build darwin || freebsd || (!cgo && linux && (amd64 || arm64)) + +package purego + +import ( + "reflect" + "runtime" + "sync" + "unsafe" +) + +var syscall9XABI0 uintptr + +type syscall9Args struct { + fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr + f1, f2, f3, f4, f5, f6, f7, f8 uintptr + r1, r2, err uintptr +} + +//go:nosplit +func syscall_syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) { + args := syscall9Args{ + fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, + a1, a2, a3, a4, a5, a6, a7, a8, + r1, r2, err, + } + runtime_cgocall(syscall9XABI0, unsafe.Pointer(&args)) + return args.r1, args.r2, args.err +} + +// NewCallback converts a Go function to a function pointer conforming to the C calling convention. +// This is useful when interoperating with C code requiring callbacks. The argument is expected to be a +// function with zero or one uintptr-sized result. The function must not have arguments with size larger than the size +// of uintptr. Only a limited number of callbacks may be created in a single Go process, and any memory allocated +// for these callbacks is never released. At least 2000 callbacks can always be created. Although this function +// provides similar functionality to windows.NewCallback it is distinct. +// +// NOTE: Linux is currently not supported and will panic if called. +func NewCallback(fn interface{}) uintptr { + if runtime.GOOS == "linux" { + panic("purego: NewCallback not supported") + } + return compileCallback(fn) +} + +// maxCb is the maximum number of callbacks +// only increase this if you have added more to the callbackasm function +const maxCB = 2000 + +var cbs struct { + lock sync.Mutex + numFn int // the number of functions currently in cbs.funcs + funcs [maxCB]reflect.Value // the saved callbacks +} + +type callbackArgs struct { + index uintptr + // args points to the argument block. + // + // The structure of the arguments goes + // float registers followed by the + // integer registers followed by the stack. + // + // This variable is treated as a continuous + // block of memory containing all of the arguments + // for this callback. + args unsafe.Pointer + // Below are out-args from callbackWrap + result uintptr +} + +func compileCallback(fn interface{}) uintptr { + val := reflect.ValueOf(fn) + if val.Kind() != reflect.Func { + panic("purego: the type must be a function but was not") + } + if val.IsNil() { + panic("purego: function must not be nil") + } + ty := val.Type() + for i := 0; i < ty.NumIn(); i++ { + in := ty.In(i) + switch in.Kind() { + case reflect.Struct, reflect.Interface, reflect.Func, reflect.Slice, + reflect.Chan, reflect.Complex64, reflect.Complex128, + reflect.String, reflect.Map, reflect.Invalid: + panic("purego: unsupported argument type: " + in.Kind().String()) + } + } +output: + switch { + case ty.NumOut() == 1: + switch ty.Out(0).Kind() { + case reflect.Pointer, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, + reflect.Bool, reflect.UnsafePointer: + break output + } + panic("purego: unsupported return type: " + ty.String()) + case ty.NumOut() > 1: + panic("purego: callbacks can only have one return") + } + cbs.lock.Lock() + defer cbs.lock.Unlock() + if cbs.numFn >= maxCB { + panic("purego: the maximum number of callbacks has been reached") + } + cbs.funcs[cbs.numFn] = val + cbs.numFn++ + return callbackasmAddr(cbs.numFn - 1) +} + +const ptrSize = unsafe.Sizeof((*int)(nil)) + +const callbackMaxFrame = 64 * ptrSize + +// callbackasm is implemented in zcallback_GOOS_GOARCH.s +// +//go:linkname __callbackasm callbackasm +var __callbackasm byte +var callbackasmABI0 = uintptr(unsafe.Pointer(&__callbackasm)) + +// callbackWrap_call allows the calling of the ABIInternal wrapper +// which is required for runtime.cgocallback without the +// tag which is only allowed in the runtime. +// This closure is used inside sys_darwin_GOARCH.s +var callbackWrap_call = callbackWrap + +// callbackWrap is called by assembly code which determines which Go function to call. +// This function takes the arguments and passes them to the Go function and returns the result. +func callbackWrap(a *callbackArgs) { + cbs.lock.Lock() + fn := cbs.funcs[a.index] + cbs.lock.Unlock() + fnType := fn.Type() + args := make([]reflect.Value, fnType.NumIn()) + frame := (*[callbackMaxFrame]uintptr)(a.args) + var floatsN int // floatsN represents the number of float arguments processed + var intsN int // intsN represents the number of integer arguments processed + // stack points to the index into frame of the current stack element. + // The stack begins after the float and integer registers. + stack := numOfIntegerRegisters() + numOfFloats + for i := range args { + var pos int + switch fnType.In(i).Kind() { + case reflect.Float32, reflect.Float64: + if floatsN >= numOfFloats { + pos = stack + stack++ + } else { + pos = floatsN + } + floatsN++ + default: + if intsN >= numOfIntegerRegisters() { + pos = stack + stack++ + } else { + // the integers begin after the floats in frame + pos = intsN + numOfFloats + } + intsN++ + } + args[i] = reflect.NewAt(fnType.In(i), unsafe.Pointer(&frame[pos])).Elem() + } + ret := fn.Call(args) + if len(ret) > 0 { + switch k := ret[0].Kind(); k { + case reflect.Uint, reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uintptr: + a.result = uintptr(ret[0].Uint()) + case reflect.Int, reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8: + a.result = uintptr(ret[0].Int()) + case reflect.Bool: + if ret[0].Bool() { + a.result = 1 + } else { + a.result = 0 + } + case reflect.Pointer: + a.result = ret[0].Pointer() + case reflect.UnsafePointer: + a.result = ret[0].Pointer() + default: + panic("purego: unsupported kind: " + k.String()) + } + } +} + +// callbackasmAddr returns address of runtime.callbackasm +// function adjusted by i. +// On x86 and amd64, runtime.callbackasm is a series of CALL instructions, +// and we want callback to arrive at +// correspondent call instruction instead of start of +// runtime.callbackasm. +// On ARM, runtime.callbackasm is a series of mov and branch instructions. +// R12 is loaded with the callback index. Each entry is two instructions, +// hence 8 bytes. +func callbackasmAddr(i int) uintptr { + var entrySize int + switch runtime.GOARCH { + default: + panic("purego: unsupported architecture") + case "386", "amd64": + entrySize = 5 + case "arm", "arm64": + // On ARM and ARM64, each entry is a MOV instruction + // followed by a branch instruction + entrySize = 8 + } + return callbackasmABI0 + uintptr(i*entrySize) +} diff --git a/vendor/github.com/ebitengine/purego/syscall_windows.go b/vendor/github.com/ebitengine/purego/syscall_windows.go new file mode 100644 index 000000000..a4db9f131 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/syscall_windows.go @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +package purego + +import ( + "syscall" + _ "unsafe" // only for go:linkname + + "golang.org/x/sys/windows" +) + +var syscall9XABI0 uintptr + +type syscall9Args struct { + fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr + f1, f2, f3, f4, f5, f6, f7, f8 uintptr + r1, r2, err uintptr +} + +func syscall_syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) { + r1, r2, errno := syscall.Syscall9(fn, 9, a1, a2, a3, a4, a5, a6, a7, a8, a9) + return r1, r2, uintptr(errno) +} + +// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention. +// This is useful when interoperating with Windows code requiring callbacks. The argument is expected to be a +// function with one uintptr-sized result. The function must not have arguments with size larger than the +// size of uintptr. Only a limited number of callbacks may be created in a single Go process, and any memory +// allocated for these callbacks is never released. Between NewCallback and NewCallbackCDecl, at least 1024 +// callbacks can always be created. Although this function is similiar to the darwin version it may act +// differently. +func NewCallback(fn interface{}) uintptr { + return syscall.NewCallback(fn) +} + +//go:linkname openLibrary openLibrary +func openLibrary(name string) (uintptr, error) { + handle, err := windows.LoadLibrary(name) + return uintptr(handle), err +} + +func loadSymbol(handle uintptr, name string) (uintptr, error) { + return windows.GetProcAddress(windows.Handle(handle), name) +} diff --git a/vendor/github.com/ebitengine/purego/zcallback_amd64.s b/vendor/github.com/ebitengine/purego/zcallback_amd64.s new file mode 100644 index 000000000..d2c750828 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/zcallback_amd64.s @@ -0,0 +1,2014 @@ +// Code generated by wincallback.go using 'go generate'. DO NOT EDIT. + +//go:build darwin || freebsd || (!cgo && linux) + +// runtime·callbackasm is called by external code to +// execute Go implemented callback function. It is not +// called from the start, instead runtime·compilecallback +// always returns address into runtime·callbackasm offset +// appropriately so different callbacks start with different +// CALL instruction in runtime·callbackasm. This determines +// which Go callback function is executed later on. +#include "textflag.h" + +TEXT callbackasm(SB), NOSPLIT|NOFRAME, $0 + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) + CALL callbackasm1(SB) diff --git a/vendor/github.com/ebitengine/purego/zcallback_arm64.s b/vendor/github.com/ebitengine/purego/zcallback_arm64.s new file mode 100644 index 000000000..fc3683d56 --- /dev/null +++ b/vendor/github.com/ebitengine/purego/zcallback_arm64.s @@ -0,0 +1,4014 @@ +// Code generated by wincallback.go using 'go generate'. DO NOT EDIT. + +//go:build darwin || freebsd || (!cgo && linux) + +// External code calls into callbackasm at an offset corresponding +// to the callback index. Callbackasm is a table of MOV and B instructions. +// The MOV instruction loads R12 with the callback index, and the +// B instruction branches to callbackasm1. +// callbackasm1 takes the callback index from R12 and +// indexes into an array that stores information about each callback. +// It then calls the Go implementation for that callback. +#include "textflag.h" + +TEXT callbackasm(SB), NOSPLIT|NOFRAME, $0 + MOVD $0, R12 + B callbackasm1(SB) + MOVD $1, R12 + B callbackasm1(SB) + MOVD $2, R12 + B callbackasm1(SB) + MOVD $3, R12 + B callbackasm1(SB) + MOVD $4, R12 + B callbackasm1(SB) + MOVD $5, R12 + B callbackasm1(SB) + MOVD $6, R12 + B callbackasm1(SB) + MOVD $7, R12 + B callbackasm1(SB) + MOVD $8, R12 + B callbackasm1(SB) + MOVD $9, R12 + B callbackasm1(SB) + MOVD $10, R12 + B callbackasm1(SB) + MOVD $11, R12 + B callbackasm1(SB) + MOVD $12, R12 + B callbackasm1(SB) + MOVD $13, R12 + B callbackasm1(SB) + MOVD $14, R12 + B callbackasm1(SB) + MOVD $15, R12 + B callbackasm1(SB) + MOVD $16, R12 + B callbackasm1(SB) + MOVD $17, R12 + B callbackasm1(SB) + MOVD $18, R12 + B callbackasm1(SB) + MOVD $19, R12 + B callbackasm1(SB) + MOVD $20, R12 + B callbackasm1(SB) + MOVD $21, R12 + B callbackasm1(SB) + MOVD $22, R12 + B callbackasm1(SB) + MOVD $23, R12 + B callbackasm1(SB) + MOVD $24, R12 + B callbackasm1(SB) + MOVD $25, R12 + B callbackasm1(SB) + MOVD $26, R12 + B callbackasm1(SB) + MOVD $27, R12 + B callbackasm1(SB) + MOVD $28, R12 + B callbackasm1(SB) + MOVD $29, R12 + B callbackasm1(SB) + MOVD $30, R12 + B callbackasm1(SB) + MOVD $31, R12 + B callbackasm1(SB) + MOVD $32, R12 + B callbackasm1(SB) + MOVD $33, R12 + B callbackasm1(SB) + MOVD $34, R12 + B callbackasm1(SB) + MOVD $35, R12 + B callbackasm1(SB) + MOVD $36, R12 + B callbackasm1(SB) + MOVD $37, R12 + B callbackasm1(SB) + MOVD $38, R12 + B callbackasm1(SB) + MOVD $39, R12 + B callbackasm1(SB) + MOVD $40, R12 + B callbackasm1(SB) + MOVD $41, R12 + B callbackasm1(SB) + MOVD $42, R12 + B callbackasm1(SB) + MOVD $43, R12 + B callbackasm1(SB) + MOVD $44, R12 + B callbackasm1(SB) + MOVD $45, R12 + B callbackasm1(SB) + MOVD $46, R12 + B callbackasm1(SB) + MOVD $47, R12 + B callbackasm1(SB) + MOVD $48, R12 + B callbackasm1(SB) + MOVD $49, R12 + B callbackasm1(SB) + MOVD $50, R12 + B callbackasm1(SB) + MOVD $51, R12 + B callbackasm1(SB) + MOVD $52, R12 + B callbackasm1(SB) + MOVD $53, R12 + B callbackasm1(SB) + MOVD $54, R12 + B callbackasm1(SB) + MOVD $55, R12 + B callbackasm1(SB) + MOVD $56, R12 + B callbackasm1(SB) + MOVD $57, R12 + B callbackasm1(SB) + MOVD $58, R12 + B callbackasm1(SB) + MOVD $59, R12 + B callbackasm1(SB) + MOVD $60, R12 + B callbackasm1(SB) + MOVD $61, R12 + B callbackasm1(SB) + MOVD $62, R12 + B callbackasm1(SB) + MOVD $63, R12 + B callbackasm1(SB) + MOVD $64, R12 + B callbackasm1(SB) + MOVD $65, R12 + B callbackasm1(SB) + MOVD $66, R12 + B callbackasm1(SB) + MOVD $67, R12 + B callbackasm1(SB) + MOVD $68, R12 + B callbackasm1(SB) + MOVD $69, R12 + B callbackasm1(SB) + MOVD $70, R12 + B callbackasm1(SB) + MOVD $71, R12 + B callbackasm1(SB) + MOVD $72, R12 + B callbackasm1(SB) + MOVD $73, R12 + B callbackasm1(SB) + MOVD $74, R12 + B callbackasm1(SB) + MOVD $75, R12 + B callbackasm1(SB) + MOVD $76, R12 + B callbackasm1(SB) + MOVD $77, R12 + B callbackasm1(SB) + MOVD $78, R12 + B callbackasm1(SB) + MOVD $79, R12 + B callbackasm1(SB) + MOVD $80, R12 + B callbackasm1(SB) + MOVD $81, R12 + B callbackasm1(SB) + MOVD $82, R12 + B callbackasm1(SB) + MOVD $83, R12 + B callbackasm1(SB) + MOVD $84, R12 + B callbackasm1(SB) + MOVD $85, R12 + B callbackasm1(SB) + MOVD $86, R12 + B callbackasm1(SB) + MOVD $87, R12 + B callbackasm1(SB) + MOVD $88, R12 + B callbackasm1(SB) + MOVD $89, R12 + B callbackasm1(SB) + MOVD $90, R12 + B callbackasm1(SB) + MOVD $91, R12 + B callbackasm1(SB) + MOVD $92, R12 + B callbackasm1(SB) + MOVD $93, R12 + B callbackasm1(SB) + MOVD $94, R12 + B callbackasm1(SB) + MOVD $95, R12 + B callbackasm1(SB) + MOVD $96, R12 + B callbackasm1(SB) + MOVD $97, R12 + B callbackasm1(SB) + MOVD $98, R12 + B callbackasm1(SB) + MOVD $99, R12 + B callbackasm1(SB) + MOVD $100, R12 + B callbackasm1(SB) + MOVD $101, R12 + B callbackasm1(SB) + MOVD $102, R12 + B callbackasm1(SB) + MOVD $103, R12 + B callbackasm1(SB) + MOVD $104, R12 + B callbackasm1(SB) + MOVD $105, R12 + B callbackasm1(SB) + MOVD $106, R12 + B callbackasm1(SB) + MOVD $107, R12 + B callbackasm1(SB) + MOVD $108, R12 + B callbackasm1(SB) + MOVD $109, R12 + B callbackasm1(SB) + MOVD $110, R12 + B callbackasm1(SB) + MOVD $111, R12 + B callbackasm1(SB) + MOVD $112, R12 + B callbackasm1(SB) + MOVD $113, R12 + B callbackasm1(SB) + MOVD $114, R12 + B callbackasm1(SB) + MOVD $115, R12 + B callbackasm1(SB) + MOVD $116, R12 + B callbackasm1(SB) + MOVD $117, R12 + B callbackasm1(SB) + MOVD $118, R12 + B callbackasm1(SB) + MOVD $119, R12 + B callbackasm1(SB) + MOVD $120, R12 + B callbackasm1(SB) + MOVD $121, R12 + B callbackasm1(SB) + MOVD $122, R12 + B callbackasm1(SB) + MOVD $123, R12 + B callbackasm1(SB) + MOVD $124, R12 + B callbackasm1(SB) + MOVD $125, R12 + B callbackasm1(SB) + MOVD $126, R12 + B callbackasm1(SB) + MOVD $127, R12 + B callbackasm1(SB) + MOVD $128, R12 + B callbackasm1(SB) + MOVD $129, R12 + B callbackasm1(SB) + MOVD $130, R12 + B callbackasm1(SB) + MOVD $131, R12 + B callbackasm1(SB) + MOVD $132, R12 + B callbackasm1(SB) + MOVD $133, R12 + B callbackasm1(SB) + MOVD $134, R12 + B callbackasm1(SB) + MOVD $135, R12 + B callbackasm1(SB) + MOVD $136, R12 + B callbackasm1(SB) + MOVD $137, R12 + B callbackasm1(SB) + MOVD $138, R12 + B callbackasm1(SB) + MOVD $139, R12 + B callbackasm1(SB) + MOVD $140, R12 + B callbackasm1(SB) + MOVD $141, R12 + B callbackasm1(SB) + MOVD $142, R12 + B callbackasm1(SB) + MOVD $143, R12 + B callbackasm1(SB) + MOVD $144, R12 + B callbackasm1(SB) + MOVD $145, R12 + B callbackasm1(SB) + MOVD $146, R12 + B callbackasm1(SB) + MOVD $147, R12 + B callbackasm1(SB) + MOVD $148, R12 + B callbackasm1(SB) + MOVD $149, R12 + B callbackasm1(SB) + MOVD $150, R12 + B callbackasm1(SB) + MOVD $151, R12 + B callbackasm1(SB) + MOVD $152, R12 + B callbackasm1(SB) + MOVD $153, R12 + B callbackasm1(SB) + MOVD $154, R12 + B callbackasm1(SB) + MOVD $155, R12 + B callbackasm1(SB) + MOVD $156, R12 + B callbackasm1(SB) + MOVD $157, R12 + B callbackasm1(SB) + MOVD $158, R12 + B callbackasm1(SB) + MOVD $159, R12 + B callbackasm1(SB) + MOVD $160, R12 + B callbackasm1(SB) + MOVD $161, R12 + B callbackasm1(SB) + MOVD $162, R12 + B callbackasm1(SB) + MOVD $163, R12 + B callbackasm1(SB) + MOVD $164, R12 + B callbackasm1(SB) + MOVD $165, R12 + B callbackasm1(SB) + MOVD $166, R12 + B callbackasm1(SB) + MOVD $167, R12 + B callbackasm1(SB) + MOVD $168, R12 + B callbackasm1(SB) + MOVD $169, R12 + B callbackasm1(SB) + MOVD $170, R12 + B callbackasm1(SB) + MOVD $171, R12 + B callbackasm1(SB) + MOVD $172, R12 + B callbackasm1(SB) + MOVD $173, R12 + B callbackasm1(SB) + MOVD $174, R12 + B callbackasm1(SB) + MOVD $175, R12 + B callbackasm1(SB) + MOVD $176, R12 + B callbackasm1(SB) + MOVD $177, R12 + B callbackasm1(SB) + MOVD $178, R12 + B callbackasm1(SB) + MOVD $179, R12 + B callbackasm1(SB) + MOVD $180, R12 + B callbackasm1(SB) + MOVD $181, R12 + B callbackasm1(SB) + MOVD $182, R12 + B callbackasm1(SB) + MOVD $183, R12 + B callbackasm1(SB) + MOVD $184, R12 + B callbackasm1(SB) + MOVD $185, R12 + B callbackasm1(SB) + MOVD $186, R12 + B callbackasm1(SB) + MOVD $187, R12 + B callbackasm1(SB) + MOVD $188, R12 + B callbackasm1(SB) + MOVD $189, R12 + B callbackasm1(SB) + MOVD $190, R12 + B callbackasm1(SB) + MOVD $191, R12 + B callbackasm1(SB) + MOVD $192, R12 + B callbackasm1(SB) + MOVD $193, R12 + B callbackasm1(SB) + MOVD $194, R12 + B callbackasm1(SB) + MOVD $195, R12 + B callbackasm1(SB) + MOVD $196, R12 + B callbackasm1(SB) + MOVD $197, R12 + B callbackasm1(SB) + MOVD $198, R12 + B callbackasm1(SB) + MOVD $199, R12 + B callbackasm1(SB) + MOVD $200, R12 + B callbackasm1(SB) + MOVD $201, R12 + B callbackasm1(SB) + MOVD $202, R12 + B callbackasm1(SB) + MOVD $203, R12 + B callbackasm1(SB) + MOVD $204, R12 + B callbackasm1(SB) + MOVD $205, R12 + B callbackasm1(SB) + MOVD $206, R12 + B callbackasm1(SB) + MOVD $207, R12 + B callbackasm1(SB) + MOVD $208, R12 + B callbackasm1(SB) + MOVD $209, R12 + B callbackasm1(SB) + MOVD $210, R12 + B callbackasm1(SB) + MOVD $211, R12 + B callbackasm1(SB) + MOVD $212, R12 + B callbackasm1(SB) + MOVD $213, R12 + B callbackasm1(SB) + MOVD $214, R12 + B callbackasm1(SB) + MOVD $215, R12 + B callbackasm1(SB) + MOVD $216, R12 + B callbackasm1(SB) + MOVD $217, R12 + B callbackasm1(SB) + MOVD $218, R12 + B callbackasm1(SB) + MOVD $219, R12 + B callbackasm1(SB) + MOVD $220, R12 + B callbackasm1(SB) + MOVD $221, R12 + B callbackasm1(SB) + MOVD $222, R12 + B callbackasm1(SB) + MOVD $223, R12 + B callbackasm1(SB) + MOVD $224, R12 + B callbackasm1(SB) + MOVD $225, R12 + B callbackasm1(SB) + MOVD $226, R12 + B callbackasm1(SB) + MOVD $227, R12 + B callbackasm1(SB) + MOVD $228, R12 + B callbackasm1(SB) + MOVD $229, R12 + B callbackasm1(SB) + MOVD $230, R12 + B callbackasm1(SB) + MOVD $231, R12 + B callbackasm1(SB) + MOVD $232, R12 + B callbackasm1(SB) + MOVD $233, R12 + B callbackasm1(SB) + MOVD $234, R12 + B callbackasm1(SB) + MOVD $235, R12 + B callbackasm1(SB) + MOVD $236, R12 + B callbackasm1(SB) + MOVD $237, R12 + B callbackasm1(SB) + MOVD $238, R12 + B callbackasm1(SB) + MOVD $239, R12 + B callbackasm1(SB) + MOVD $240, R12 + B callbackasm1(SB) + MOVD $241, R12 + B callbackasm1(SB) + MOVD $242, R12 + B callbackasm1(SB) + MOVD $243, R12 + B callbackasm1(SB) + MOVD $244, R12 + B callbackasm1(SB) + MOVD $245, R12 + B callbackasm1(SB) + MOVD $246, R12 + B callbackasm1(SB) + MOVD $247, R12 + B callbackasm1(SB) + MOVD $248, R12 + B callbackasm1(SB) + MOVD $249, R12 + B callbackasm1(SB) + MOVD $250, R12 + B callbackasm1(SB) + MOVD $251, R12 + B callbackasm1(SB) + MOVD $252, R12 + B callbackasm1(SB) + MOVD $253, R12 + B callbackasm1(SB) + MOVD $254, R12 + B callbackasm1(SB) + MOVD $255, R12 + B callbackasm1(SB) + MOVD $256, R12 + B callbackasm1(SB) + MOVD $257, R12 + B callbackasm1(SB) + MOVD $258, R12 + B callbackasm1(SB) + MOVD $259, R12 + B callbackasm1(SB) + MOVD $260, R12 + B callbackasm1(SB) + MOVD $261, R12 + B callbackasm1(SB) + MOVD $262, R12 + B callbackasm1(SB) + MOVD $263, R12 + B callbackasm1(SB) + MOVD $264, R12 + B callbackasm1(SB) + MOVD $265, R12 + B callbackasm1(SB) + MOVD $266, R12 + B callbackasm1(SB) + MOVD $267, R12 + B callbackasm1(SB) + MOVD $268, R12 + B callbackasm1(SB) + MOVD $269, R12 + B callbackasm1(SB) + MOVD $270, R12 + B callbackasm1(SB) + MOVD $271, R12 + B callbackasm1(SB) + MOVD $272, R12 + B callbackasm1(SB) + MOVD $273, R12 + B callbackasm1(SB) + MOVD $274, R12 + B callbackasm1(SB) + MOVD $275, R12 + B callbackasm1(SB) + MOVD $276, R12 + B callbackasm1(SB) + MOVD $277, R12 + B callbackasm1(SB) + MOVD $278, R12 + B callbackasm1(SB) + MOVD $279, R12 + B callbackasm1(SB) + MOVD $280, R12 + B callbackasm1(SB) + MOVD $281, R12 + B callbackasm1(SB) + MOVD $282, R12 + B callbackasm1(SB) + MOVD $283, R12 + B callbackasm1(SB) + MOVD $284, R12 + B callbackasm1(SB) + MOVD $285, R12 + B callbackasm1(SB) + MOVD $286, R12 + B callbackasm1(SB) + MOVD $287, R12 + B callbackasm1(SB) + MOVD $288, R12 + B callbackasm1(SB) + MOVD $289, R12 + B callbackasm1(SB) + MOVD $290, R12 + B callbackasm1(SB) + MOVD $291, R12 + B callbackasm1(SB) + MOVD $292, R12 + B callbackasm1(SB) + MOVD $293, R12 + B callbackasm1(SB) + MOVD $294, R12 + B callbackasm1(SB) + MOVD $295, R12 + B callbackasm1(SB) + MOVD $296, R12 + B callbackasm1(SB) + MOVD $297, R12 + B callbackasm1(SB) + MOVD $298, R12 + B callbackasm1(SB) + MOVD $299, R12 + B callbackasm1(SB) + MOVD $300, R12 + B callbackasm1(SB) + MOVD $301, R12 + B callbackasm1(SB) + MOVD $302, R12 + B callbackasm1(SB) + MOVD $303, R12 + B callbackasm1(SB) + MOVD $304, R12 + B callbackasm1(SB) + MOVD $305, R12 + B callbackasm1(SB) + MOVD $306, R12 + B callbackasm1(SB) + MOVD $307, R12 + B callbackasm1(SB) + MOVD $308, R12 + B callbackasm1(SB) + MOVD $309, R12 + B callbackasm1(SB) + MOVD $310, R12 + B callbackasm1(SB) + MOVD $311, R12 + B callbackasm1(SB) + MOVD $312, R12 + B callbackasm1(SB) + MOVD $313, R12 + B callbackasm1(SB) + MOVD $314, R12 + B callbackasm1(SB) + MOVD $315, R12 + B callbackasm1(SB) + MOVD $316, R12 + B callbackasm1(SB) + MOVD $317, R12 + B callbackasm1(SB) + MOVD $318, R12 + B callbackasm1(SB) + MOVD $319, R12 + B callbackasm1(SB) + MOVD $320, R12 + B callbackasm1(SB) + MOVD $321, R12 + B callbackasm1(SB) + MOVD $322, R12 + B callbackasm1(SB) + MOVD $323, R12 + B callbackasm1(SB) + MOVD $324, R12 + B callbackasm1(SB) + MOVD $325, R12 + B callbackasm1(SB) + MOVD $326, R12 + B callbackasm1(SB) + MOVD $327, R12 + B callbackasm1(SB) + MOVD $328, R12 + B callbackasm1(SB) + MOVD $329, R12 + B callbackasm1(SB) + MOVD $330, R12 + B callbackasm1(SB) + MOVD $331, R12 + B callbackasm1(SB) + MOVD $332, R12 + B callbackasm1(SB) + MOVD $333, R12 + B callbackasm1(SB) + MOVD $334, R12 + B callbackasm1(SB) + MOVD $335, R12 + B callbackasm1(SB) + MOVD $336, R12 + B callbackasm1(SB) + MOVD $337, R12 + B callbackasm1(SB) + MOVD $338, R12 + B callbackasm1(SB) + MOVD $339, R12 + B callbackasm1(SB) + MOVD $340, R12 + B callbackasm1(SB) + MOVD $341, R12 + B callbackasm1(SB) + MOVD $342, R12 + B callbackasm1(SB) + MOVD $343, R12 + B callbackasm1(SB) + MOVD $344, R12 + B callbackasm1(SB) + MOVD $345, R12 + B callbackasm1(SB) + MOVD $346, R12 + B callbackasm1(SB) + MOVD $347, R12 + B callbackasm1(SB) + MOVD $348, R12 + B callbackasm1(SB) + MOVD $349, R12 + B callbackasm1(SB) + MOVD $350, R12 + B callbackasm1(SB) + MOVD $351, R12 + B callbackasm1(SB) + MOVD $352, R12 + B callbackasm1(SB) + MOVD $353, R12 + B callbackasm1(SB) + MOVD $354, R12 + B callbackasm1(SB) + MOVD $355, R12 + B callbackasm1(SB) + MOVD $356, R12 + B callbackasm1(SB) + MOVD $357, R12 + B callbackasm1(SB) + MOVD $358, R12 + B callbackasm1(SB) + MOVD $359, R12 + B callbackasm1(SB) + MOVD $360, R12 + B callbackasm1(SB) + MOVD $361, R12 + B callbackasm1(SB) + MOVD $362, R12 + B callbackasm1(SB) + MOVD $363, R12 + B callbackasm1(SB) + MOVD $364, R12 + B callbackasm1(SB) + MOVD $365, R12 + B callbackasm1(SB) + MOVD $366, R12 + B callbackasm1(SB) + MOVD $367, R12 + B callbackasm1(SB) + MOVD $368, R12 + B callbackasm1(SB) + MOVD $369, R12 + B callbackasm1(SB) + MOVD $370, R12 + B callbackasm1(SB) + MOVD $371, R12 + B callbackasm1(SB) + MOVD $372, R12 + B callbackasm1(SB) + MOVD $373, R12 + B callbackasm1(SB) + MOVD $374, R12 + B callbackasm1(SB) + MOVD $375, R12 + B callbackasm1(SB) + MOVD $376, R12 + B callbackasm1(SB) + MOVD $377, R12 + B callbackasm1(SB) + MOVD $378, R12 + B callbackasm1(SB) + MOVD $379, R12 + B callbackasm1(SB) + MOVD $380, R12 + B callbackasm1(SB) + MOVD $381, R12 + B callbackasm1(SB) + MOVD $382, R12 + B callbackasm1(SB) + MOVD $383, R12 + B callbackasm1(SB) + MOVD $384, R12 + B callbackasm1(SB) + MOVD $385, R12 + B callbackasm1(SB) + MOVD $386, R12 + B callbackasm1(SB) + MOVD $387, R12 + B callbackasm1(SB) + MOVD $388, R12 + B callbackasm1(SB) + MOVD $389, R12 + B callbackasm1(SB) + MOVD $390, R12 + B callbackasm1(SB) + MOVD $391, R12 + B callbackasm1(SB) + MOVD $392, R12 + B callbackasm1(SB) + MOVD $393, R12 + B callbackasm1(SB) + MOVD $394, R12 + B callbackasm1(SB) + MOVD $395, R12 + B callbackasm1(SB) + MOVD $396, R12 + B callbackasm1(SB) + MOVD $397, R12 + B callbackasm1(SB) + MOVD $398, R12 + B callbackasm1(SB) + MOVD $399, R12 + B callbackasm1(SB) + MOVD $400, R12 + B callbackasm1(SB) + MOVD $401, R12 + B callbackasm1(SB) + MOVD $402, R12 + B callbackasm1(SB) + MOVD $403, R12 + B callbackasm1(SB) + MOVD $404, R12 + B callbackasm1(SB) + MOVD $405, R12 + B callbackasm1(SB) + MOVD $406, R12 + B callbackasm1(SB) + MOVD $407, R12 + B callbackasm1(SB) + MOVD $408, R12 + B callbackasm1(SB) + MOVD $409, R12 + B callbackasm1(SB) + MOVD $410, R12 + B callbackasm1(SB) + MOVD $411, R12 + B callbackasm1(SB) + MOVD $412, R12 + B callbackasm1(SB) + MOVD $413, R12 + B callbackasm1(SB) + MOVD $414, R12 + B callbackasm1(SB) + MOVD $415, R12 + B callbackasm1(SB) + MOVD $416, R12 + B callbackasm1(SB) + MOVD $417, R12 + B callbackasm1(SB) + MOVD $418, R12 + B callbackasm1(SB) + MOVD $419, R12 + B callbackasm1(SB) + MOVD $420, R12 + B callbackasm1(SB) + MOVD $421, R12 + B callbackasm1(SB) + MOVD $422, R12 + B callbackasm1(SB) + MOVD $423, R12 + B callbackasm1(SB) + MOVD $424, R12 + B callbackasm1(SB) + MOVD $425, R12 + B callbackasm1(SB) + MOVD $426, R12 + B callbackasm1(SB) + MOVD $427, R12 + B callbackasm1(SB) + MOVD $428, R12 + B callbackasm1(SB) + MOVD $429, R12 + B callbackasm1(SB) + MOVD $430, R12 + B callbackasm1(SB) + MOVD $431, R12 + B callbackasm1(SB) + MOVD $432, R12 + B callbackasm1(SB) + MOVD $433, R12 + B callbackasm1(SB) + MOVD $434, R12 + B callbackasm1(SB) + MOVD $435, R12 + B callbackasm1(SB) + MOVD $436, R12 + B callbackasm1(SB) + MOVD $437, R12 + B callbackasm1(SB) + MOVD $438, R12 + B callbackasm1(SB) + MOVD $439, R12 + B callbackasm1(SB) + MOVD $440, R12 + B callbackasm1(SB) + MOVD $441, R12 + B callbackasm1(SB) + MOVD $442, R12 + B callbackasm1(SB) + MOVD $443, R12 + B callbackasm1(SB) + MOVD $444, R12 + B callbackasm1(SB) + MOVD $445, R12 + B callbackasm1(SB) + MOVD $446, R12 + B callbackasm1(SB) + MOVD $447, R12 + B callbackasm1(SB) + MOVD $448, R12 + B callbackasm1(SB) + MOVD $449, R12 + B callbackasm1(SB) + MOVD $450, R12 + B callbackasm1(SB) + MOVD $451, R12 + B callbackasm1(SB) + MOVD $452, R12 + B callbackasm1(SB) + MOVD $453, R12 + B callbackasm1(SB) + MOVD $454, R12 + B callbackasm1(SB) + MOVD $455, R12 + B callbackasm1(SB) + MOVD $456, R12 + B callbackasm1(SB) + MOVD $457, R12 + B callbackasm1(SB) + MOVD $458, R12 + B callbackasm1(SB) + MOVD $459, R12 + B callbackasm1(SB) + MOVD $460, R12 + B callbackasm1(SB) + MOVD $461, R12 + B callbackasm1(SB) + MOVD $462, R12 + B callbackasm1(SB) + MOVD $463, R12 + B callbackasm1(SB) + MOVD $464, R12 + B callbackasm1(SB) + MOVD $465, R12 + B callbackasm1(SB) + MOVD $466, R12 + B callbackasm1(SB) + MOVD $467, R12 + B callbackasm1(SB) + MOVD $468, R12 + B callbackasm1(SB) + MOVD $469, R12 + B callbackasm1(SB) + MOVD $470, R12 + B callbackasm1(SB) + MOVD $471, R12 + B callbackasm1(SB) + MOVD $472, R12 + B callbackasm1(SB) + MOVD $473, R12 + B callbackasm1(SB) + MOVD $474, R12 + B callbackasm1(SB) + MOVD $475, R12 + B callbackasm1(SB) + MOVD $476, R12 + B callbackasm1(SB) + MOVD $477, R12 + B callbackasm1(SB) + MOVD $478, R12 + B callbackasm1(SB) + MOVD $479, R12 + B callbackasm1(SB) + MOVD $480, R12 + B callbackasm1(SB) + MOVD $481, R12 + B callbackasm1(SB) + MOVD $482, R12 + B callbackasm1(SB) + MOVD $483, R12 + B callbackasm1(SB) + MOVD $484, R12 + B callbackasm1(SB) + MOVD $485, R12 + B callbackasm1(SB) + MOVD $486, R12 + B callbackasm1(SB) + MOVD $487, R12 + B callbackasm1(SB) + MOVD $488, R12 + B callbackasm1(SB) + MOVD $489, R12 + B callbackasm1(SB) + MOVD $490, R12 + B callbackasm1(SB) + MOVD $491, R12 + B callbackasm1(SB) + MOVD $492, R12 + B callbackasm1(SB) + MOVD $493, R12 + B callbackasm1(SB) + MOVD $494, R12 + B callbackasm1(SB) + MOVD $495, R12 + B callbackasm1(SB) + MOVD $496, R12 + B callbackasm1(SB) + MOVD $497, R12 + B callbackasm1(SB) + MOVD $498, R12 + B callbackasm1(SB) + MOVD $499, R12 + B callbackasm1(SB) + MOVD $500, R12 + B callbackasm1(SB) + MOVD $501, R12 + B callbackasm1(SB) + MOVD $502, R12 + B callbackasm1(SB) + MOVD $503, R12 + B callbackasm1(SB) + MOVD $504, R12 + B callbackasm1(SB) + MOVD $505, R12 + B callbackasm1(SB) + MOVD $506, R12 + B callbackasm1(SB) + MOVD $507, R12 + B callbackasm1(SB) + MOVD $508, R12 + B callbackasm1(SB) + MOVD $509, R12 + B callbackasm1(SB) + MOVD $510, R12 + B callbackasm1(SB) + MOVD $511, R12 + B callbackasm1(SB) + MOVD $512, R12 + B callbackasm1(SB) + MOVD $513, R12 + B callbackasm1(SB) + MOVD $514, R12 + B callbackasm1(SB) + MOVD $515, R12 + B callbackasm1(SB) + MOVD $516, R12 + B callbackasm1(SB) + MOVD $517, R12 + B callbackasm1(SB) + MOVD $518, R12 + B callbackasm1(SB) + MOVD $519, R12 + B callbackasm1(SB) + MOVD $520, R12 + B callbackasm1(SB) + MOVD $521, R12 + B callbackasm1(SB) + MOVD $522, R12 + B callbackasm1(SB) + MOVD $523, R12 + B callbackasm1(SB) + MOVD $524, R12 + B callbackasm1(SB) + MOVD $525, R12 + B callbackasm1(SB) + MOVD $526, R12 + B callbackasm1(SB) + MOVD $527, R12 + B callbackasm1(SB) + MOVD $528, R12 + B callbackasm1(SB) + MOVD $529, R12 + B callbackasm1(SB) + MOVD $530, R12 + B callbackasm1(SB) + MOVD $531, R12 + B callbackasm1(SB) + MOVD $532, R12 + B callbackasm1(SB) + MOVD $533, R12 + B callbackasm1(SB) + MOVD $534, R12 + B callbackasm1(SB) + MOVD $535, R12 + B callbackasm1(SB) + MOVD $536, R12 + B callbackasm1(SB) + MOVD $537, R12 + B callbackasm1(SB) + MOVD $538, R12 + B callbackasm1(SB) + MOVD $539, R12 + B callbackasm1(SB) + MOVD $540, R12 + B callbackasm1(SB) + MOVD $541, R12 + B callbackasm1(SB) + MOVD $542, R12 + B callbackasm1(SB) + MOVD $543, R12 + B callbackasm1(SB) + MOVD $544, R12 + B callbackasm1(SB) + MOVD $545, R12 + B callbackasm1(SB) + MOVD $546, R12 + B callbackasm1(SB) + MOVD $547, R12 + B callbackasm1(SB) + MOVD $548, R12 + B callbackasm1(SB) + MOVD $549, R12 + B callbackasm1(SB) + MOVD $550, R12 + B callbackasm1(SB) + MOVD $551, R12 + B callbackasm1(SB) + MOVD $552, R12 + B callbackasm1(SB) + MOVD $553, R12 + B callbackasm1(SB) + MOVD $554, R12 + B callbackasm1(SB) + MOVD $555, R12 + B callbackasm1(SB) + MOVD $556, R12 + B callbackasm1(SB) + MOVD $557, R12 + B callbackasm1(SB) + MOVD $558, R12 + B callbackasm1(SB) + MOVD $559, R12 + B callbackasm1(SB) + MOVD $560, R12 + B callbackasm1(SB) + MOVD $561, R12 + B callbackasm1(SB) + MOVD $562, R12 + B callbackasm1(SB) + MOVD $563, R12 + B callbackasm1(SB) + MOVD $564, R12 + B callbackasm1(SB) + MOVD $565, R12 + B callbackasm1(SB) + MOVD $566, R12 + B callbackasm1(SB) + MOVD $567, R12 + B callbackasm1(SB) + MOVD $568, R12 + B callbackasm1(SB) + MOVD $569, R12 + B callbackasm1(SB) + MOVD $570, R12 + B callbackasm1(SB) + MOVD $571, R12 + B callbackasm1(SB) + MOVD $572, R12 + B callbackasm1(SB) + MOVD $573, R12 + B callbackasm1(SB) + MOVD $574, R12 + B callbackasm1(SB) + MOVD $575, R12 + B callbackasm1(SB) + MOVD $576, R12 + B callbackasm1(SB) + MOVD $577, R12 + B callbackasm1(SB) + MOVD $578, R12 + B callbackasm1(SB) + MOVD $579, R12 + B callbackasm1(SB) + MOVD $580, R12 + B callbackasm1(SB) + MOVD $581, R12 + B callbackasm1(SB) + MOVD $582, R12 + B callbackasm1(SB) + MOVD $583, R12 + B callbackasm1(SB) + MOVD $584, R12 + B callbackasm1(SB) + MOVD $585, R12 + B callbackasm1(SB) + MOVD $586, R12 + B callbackasm1(SB) + MOVD $587, R12 + B callbackasm1(SB) + MOVD $588, R12 + B callbackasm1(SB) + MOVD $589, R12 + B callbackasm1(SB) + MOVD $590, R12 + B callbackasm1(SB) + MOVD $591, R12 + B callbackasm1(SB) + MOVD $592, R12 + B callbackasm1(SB) + MOVD $593, R12 + B callbackasm1(SB) + MOVD $594, R12 + B callbackasm1(SB) + MOVD $595, R12 + B callbackasm1(SB) + MOVD $596, R12 + B callbackasm1(SB) + MOVD $597, R12 + B callbackasm1(SB) + MOVD $598, R12 + B callbackasm1(SB) + MOVD $599, R12 + B callbackasm1(SB) + MOVD $600, R12 + B callbackasm1(SB) + MOVD $601, R12 + B callbackasm1(SB) + MOVD $602, R12 + B callbackasm1(SB) + MOVD $603, R12 + B callbackasm1(SB) + MOVD $604, R12 + B callbackasm1(SB) + MOVD $605, R12 + B callbackasm1(SB) + MOVD $606, R12 + B callbackasm1(SB) + MOVD $607, R12 + B callbackasm1(SB) + MOVD $608, R12 + B callbackasm1(SB) + MOVD $609, R12 + B callbackasm1(SB) + MOVD $610, R12 + B callbackasm1(SB) + MOVD $611, R12 + B callbackasm1(SB) + MOVD $612, R12 + B callbackasm1(SB) + MOVD $613, R12 + B callbackasm1(SB) + MOVD $614, R12 + B callbackasm1(SB) + MOVD $615, R12 + B callbackasm1(SB) + MOVD $616, R12 + B callbackasm1(SB) + MOVD $617, R12 + B callbackasm1(SB) + MOVD $618, R12 + B callbackasm1(SB) + MOVD $619, R12 + B callbackasm1(SB) + MOVD $620, R12 + B callbackasm1(SB) + MOVD $621, R12 + B callbackasm1(SB) + MOVD $622, R12 + B callbackasm1(SB) + MOVD $623, R12 + B callbackasm1(SB) + MOVD $624, R12 + B callbackasm1(SB) + MOVD $625, R12 + B callbackasm1(SB) + MOVD $626, R12 + B callbackasm1(SB) + MOVD $627, R12 + B callbackasm1(SB) + MOVD $628, R12 + B callbackasm1(SB) + MOVD $629, R12 + B callbackasm1(SB) + MOVD $630, R12 + B callbackasm1(SB) + MOVD $631, R12 + B callbackasm1(SB) + MOVD $632, R12 + B callbackasm1(SB) + MOVD $633, R12 + B callbackasm1(SB) + MOVD $634, R12 + B callbackasm1(SB) + MOVD $635, R12 + B callbackasm1(SB) + MOVD $636, R12 + B callbackasm1(SB) + MOVD $637, R12 + B callbackasm1(SB) + MOVD $638, R12 + B callbackasm1(SB) + MOVD $639, R12 + B callbackasm1(SB) + MOVD $640, R12 + B callbackasm1(SB) + MOVD $641, R12 + B callbackasm1(SB) + MOVD $642, R12 + B callbackasm1(SB) + MOVD $643, R12 + B callbackasm1(SB) + MOVD $644, R12 + B callbackasm1(SB) + MOVD $645, R12 + B callbackasm1(SB) + MOVD $646, R12 + B callbackasm1(SB) + MOVD $647, R12 + B callbackasm1(SB) + MOVD $648, R12 + B callbackasm1(SB) + MOVD $649, R12 + B callbackasm1(SB) + MOVD $650, R12 + B callbackasm1(SB) + MOVD $651, R12 + B callbackasm1(SB) + MOVD $652, R12 + B callbackasm1(SB) + MOVD $653, R12 + B callbackasm1(SB) + MOVD $654, R12 + B callbackasm1(SB) + MOVD $655, R12 + B callbackasm1(SB) + MOVD $656, R12 + B callbackasm1(SB) + MOVD $657, R12 + B callbackasm1(SB) + MOVD $658, R12 + B callbackasm1(SB) + MOVD $659, R12 + B callbackasm1(SB) + MOVD $660, R12 + B callbackasm1(SB) + MOVD $661, R12 + B callbackasm1(SB) + MOVD $662, R12 + B callbackasm1(SB) + MOVD $663, R12 + B callbackasm1(SB) + MOVD $664, R12 + B callbackasm1(SB) + MOVD $665, R12 + B callbackasm1(SB) + MOVD $666, R12 + B callbackasm1(SB) + MOVD $667, R12 + B callbackasm1(SB) + MOVD $668, R12 + B callbackasm1(SB) + MOVD $669, R12 + B callbackasm1(SB) + MOVD $670, R12 + B callbackasm1(SB) + MOVD $671, R12 + B callbackasm1(SB) + MOVD $672, R12 + B callbackasm1(SB) + MOVD $673, R12 + B callbackasm1(SB) + MOVD $674, R12 + B callbackasm1(SB) + MOVD $675, R12 + B callbackasm1(SB) + MOVD $676, R12 + B callbackasm1(SB) + MOVD $677, R12 + B callbackasm1(SB) + MOVD $678, R12 + B callbackasm1(SB) + MOVD $679, R12 + B callbackasm1(SB) + MOVD $680, R12 + B callbackasm1(SB) + MOVD $681, R12 + B callbackasm1(SB) + MOVD $682, R12 + B callbackasm1(SB) + MOVD $683, R12 + B callbackasm1(SB) + MOVD $684, R12 + B callbackasm1(SB) + MOVD $685, R12 + B callbackasm1(SB) + MOVD $686, R12 + B callbackasm1(SB) + MOVD $687, R12 + B callbackasm1(SB) + MOVD $688, R12 + B callbackasm1(SB) + MOVD $689, R12 + B callbackasm1(SB) + MOVD $690, R12 + B callbackasm1(SB) + MOVD $691, R12 + B callbackasm1(SB) + MOVD $692, R12 + B callbackasm1(SB) + MOVD $693, R12 + B callbackasm1(SB) + MOVD $694, R12 + B callbackasm1(SB) + MOVD $695, R12 + B callbackasm1(SB) + MOVD $696, R12 + B callbackasm1(SB) + MOVD $697, R12 + B callbackasm1(SB) + MOVD $698, R12 + B callbackasm1(SB) + MOVD $699, R12 + B callbackasm1(SB) + MOVD $700, R12 + B callbackasm1(SB) + MOVD $701, R12 + B callbackasm1(SB) + MOVD $702, R12 + B callbackasm1(SB) + MOVD $703, R12 + B callbackasm1(SB) + MOVD $704, R12 + B callbackasm1(SB) + MOVD $705, R12 + B callbackasm1(SB) + MOVD $706, R12 + B callbackasm1(SB) + MOVD $707, R12 + B callbackasm1(SB) + MOVD $708, R12 + B callbackasm1(SB) + MOVD $709, R12 + B callbackasm1(SB) + MOVD $710, R12 + B callbackasm1(SB) + MOVD $711, R12 + B callbackasm1(SB) + MOVD $712, R12 + B callbackasm1(SB) + MOVD $713, R12 + B callbackasm1(SB) + MOVD $714, R12 + B callbackasm1(SB) + MOVD $715, R12 + B callbackasm1(SB) + MOVD $716, R12 + B callbackasm1(SB) + MOVD $717, R12 + B callbackasm1(SB) + MOVD $718, R12 + B callbackasm1(SB) + MOVD $719, R12 + B callbackasm1(SB) + MOVD $720, R12 + B callbackasm1(SB) + MOVD $721, R12 + B callbackasm1(SB) + MOVD $722, R12 + B callbackasm1(SB) + MOVD $723, R12 + B callbackasm1(SB) + MOVD $724, R12 + B callbackasm1(SB) + MOVD $725, R12 + B callbackasm1(SB) + MOVD $726, R12 + B callbackasm1(SB) + MOVD $727, R12 + B callbackasm1(SB) + MOVD $728, R12 + B callbackasm1(SB) + MOVD $729, R12 + B callbackasm1(SB) + MOVD $730, R12 + B callbackasm1(SB) + MOVD $731, R12 + B callbackasm1(SB) + MOVD $732, R12 + B callbackasm1(SB) + MOVD $733, R12 + B callbackasm1(SB) + MOVD $734, R12 + B callbackasm1(SB) + MOVD $735, R12 + B callbackasm1(SB) + MOVD $736, R12 + B callbackasm1(SB) + MOVD $737, R12 + B callbackasm1(SB) + MOVD $738, R12 + B callbackasm1(SB) + MOVD $739, R12 + B callbackasm1(SB) + MOVD $740, R12 + B callbackasm1(SB) + MOVD $741, R12 + B callbackasm1(SB) + MOVD $742, R12 + B callbackasm1(SB) + MOVD $743, R12 + B callbackasm1(SB) + MOVD $744, R12 + B callbackasm1(SB) + MOVD $745, R12 + B callbackasm1(SB) + MOVD $746, R12 + B callbackasm1(SB) + MOVD $747, R12 + B callbackasm1(SB) + MOVD $748, R12 + B callbackasm1(SB) + MOVD $749, R12 + B callbackasm1(SB) + MOVD $750, R12 + B callbackasm1(SB) + MOVD $751, R12 + B callbackasm1(SB) + MOVD $752, R12 + B callbackasm1(SB) + MOVD $753, R12 + B callbackasm1(SB) + MOVD $754, R12 + B callbackasm1(SB) + MOVD $755, R12 + B callbackasm1(SB) + MOVD $756, R12 + B callbackasm1(SB) + MOVD $757, R12 + B callbackasm1(SB) + MOVD $758, R12 + B callbackasm1(SB) + MOVD $759, R12 + B callbackasm1(SB) + MOVD $760, R12 + B callbackasm1(SB) + MOVD $761, R12 + B callbackasm1(SB) + MOVD $762, R12 + B callbackasm1(SB) + MOVD $763, R12 + B callbackasm1(SB) + MOVD $764, R12 + B callbackasm1(SB) + MOVD $765, R12 + B callbackasm1(SB) + MOVD $766, R12 + B callbackasm1(SB) + MOVD $767, R12 + B callbackasm1(SB) + MOVD $768, R12 + B callbackasm1(SB) + MOVD $769, R12 + B callbackasm1(SB) + MOVD $770, R12 + B callbackasm1(SB) + MOVD $771, R12 + B callbackasm1(SB) + MOVD $772, R12 + B callbackasm1(SB) + MOVD $773, R12 + B callbackasm1(SB) + MOVD $774, R12 + B callbackasm1(SB) + MOVD $775, R12 + B callbackasm1(SB) + MOVD $776, R12 + B callbackasm1(SB) + MOVD $777, R12 + B callbackasm1(SB) + MOVD $778, R12 + B callbackasm1(SB) + MOVD $779, R12 + B callbackasm1(SB) + MOVD $780, R12 + B callbackasm1(SB) + MOVD $781, R12 + B callbackasm1(SB) + MOVD $782, R12 + B callbackasm1(SB) + MOVD $783, R12 + B callbackasm1(SB) + MOVD $784, R12 + B callbackasm1(SB) + MOVD $785, R12 + B callbackasm1(SB) + MOVD $786, R12 + B callbackasm1(SB) + MOVD $787, R12 + B callbackasm1(SB) + MOVD $788, R12 + B callbackasm1(SB) + MOVD $789, R12 + B callbackasm1(SB) + MOVD $790, R12 + B callbackasm1(SB) + MOVD $791, R12 + B callbackasm1(SB) + MOVD $792, R12 + B callbackasm1(SB) + MOVD $793, R12 + B callbackasm1(SB) + MOVD $794, R12 + B callbackasm1(SB) + MOVD $795, R12 + B callbackasm1(SB) + MOVD $796, R12 + B callbackasm1(SB) + MOVD $797, R12 + B callbackasm1(SB) + MOVD $798, R12 + B callbackasm1(SB) + MOVD $799, R12 + B callbackasm1(SB) + MOVD $800, R12 + B callbackasm1(SB) + MOVD $801, R12 + B callbackasm1(SB) + MOVD $802, R12 + B callbackasm1(SB) + MOVD $803, R12 + B callbackasm1(SB) + MOVD $804, R12 + B callbackasm1(SB) + MOVD $805, R12 + B callbackasm1(SB) + MOVD $806, R12 + B callbackasm1(SB) + MOVD $807, R12 + B callbackasm1(SB) + MOVD $808, R12 + B callbackasm1(SB) + MOVD $809, R12 + B callbackasm1(SB) + MOVD $810, R12 + B callbackasm1(SB) + MOVD $811, R12 + B callbackasm1(SB) + MOVD $812, R12 + B callbackasm1(SB) + MOVD $813, R12 + B callbackasm1(SB) + MOVD $814, R12 + B callbackasm1(SB) + MOVD $815, R12 + B callbackasm1(SB) + MOVD $816, R12 + B callbackasm1(SB) + MOVD $817, R12 + B callbackasm1(SB) + MOVD $818, R12 + B callbackasm1(SB) + MOVD $819, R12 + B callbackasm1(SB) + MOVD $820, R12 + B callbackasm1(SB) + MOVD $821, R12 + B callbackasm1(SB) + MOVD $822, R12 + B callbackasm1(SB) + MOVD $823, R12 + B callbackasm1(SB) + MOVD $824, R12 + B callbackasm1(SB) + MOVD $825, R12 + B callbackasm1(SB) + MOVD $826, R12 + B callbackasm1(SB) + MOVD $827, R12 + B callbackasm1(SB) + MOVD $828, R12 + B callbackasm1(SB) + MOVD $829, R12 + B callbackasm1(SB) + MOVD $830, R12 + B callbackasm1(SB) + MOVD $831, R12 + B callbackasm1(SB) + MOVD $832, R12 + B callbackasm1(SB) + MOVD $833, R12 + B callbackasm1(SB) + MOVD $834, R12 + B callbackasm1(SB) + MOVD $835, R12 + B callbackasm1(SB) + MOVD $836, R12 + B callbackasm1(SB) + MOVD $837, R12 + B callbackasm1(SB) + MOVD $838, R12 + B callbackasm1(SB) + MOVD $839, R12 + B callbackasm1(SB) + MOVD $840, R12 + B callbackasm1(SB) + MOVD $841, R12 + B callbackasm1(SB) + MOVD $842, R12 + B callbackasm1(SB) + MOVD $843, R12 + B callbackasm1(SB) + MOVD $844, R12 + B callbackasm1(SB) + MOVD $845, R12 + B callbackasm1(SB) + MOVD $846, R12 + B callbackasm1(SB) + MOVD $847, R12 + B callbackasm1(SB) + MOVD $848, R12 + B callbackasm1(SB) + MOVD $849, R12 + B callbackasm1(SB) + MOVD $850, R12 + B callbackasm1(SB) + MOVD $851, R12 + B callbackasm1(SB) + MOVD $852, R12 + B callbackasm1(SB) + MOVD $853, R12 + B callbackasm1(SB) + MOVD $854, R12 + B callbackasm1(SB) + MOVD $855, R12 + B callbackasm1(SB) + MOVD $856, R12 + B callbackasm1(SB) + MOVD $857, R12 + B callbackasm1(SB) + MOVD $858, R12 + B callbackasm1(SB) + MOVD $859, R12 + B callbackasm1(SB) + MOVD $860, R12 + B callbackasm1(SB) + MOVD $861, R12 + B callbackasm1(SB) + MOVD $862, R12 + B callbackasm1(SB) + MOVD $863, R12 + B callbackasm1(SB) + MOVD $864, R12 + B callbackasm1(SB) + MOVD $865, R12 + B callbackasm1(SB) + MOVD $866, R12 + B callbackasm1(SB) + MOVD $867, R12 + B callbackasm1(SB) + MOVD $868, R12 + B callbackasm1(SB) + MOVD $869, R12 + B callbackasm1(SB) + MOVD $870, R12 + B callbackasm1(SB) + MOVD $871, R12 + B callbackasm1(SB) + MOVD $872, R12 + B callbackasm1(SB) + MOVD $873, R12 + B callbackasm1(SB) + MOVD $874, R12 + B callbackasm1(SB) + MOVD $875, R12 + B callbackasm1(SB) + MOVD $876, R12 + B callbackasm1(SB) + MOVD $877, R12 + B callbackasm1(SB) + MOVD $878, R12 + B callbackasm1(SB) + MOVD $879, R12 + B callbackasm1(SB) + MOVD $880, R12 + B callbackasm1(SB) + MOVD $881, R12 + B callbackasm1(SB) + MOVD $882, R12 + B callbackasm1(SB) + MOVD $883, R12 + B callbackasm1(SB) + MOVD $884, R12 + B callbackasm1(SB) + MOVD $885, R12 + B callbackasm1(SB) + MOVD $886, R12 + B callbackasm1(SB) + MOVD $887, R12 + B callbackasm1(SB) + MOVD $888, R12 + B callbackasm1(SB) + MOVD $889, R12 + B callbackasm1(SB) + MOVD $890, R12 + B callbackasm1(SB) + MOVD $891, R12 + B callbackasm1(SB) + MOVD $892, R12 + B callbackasm1(SB) + MOVD $893, R12 + B callbackasm1(SB) + MOVD $894, R12 + B callbackasm1(SB) + MOVD $895, R12 + B callbackasm1(SB) + MOVD $896, R12 + B callbackasm1(SB) + MOVD $897, R12 + B callbackasm1(SB) + MOVD $898, R12 + B callbackasm1(SB) + MOVD $899, R12 + B callbackasm1(SB) + MOVD $900, R12 + B callbackasm1(SB) + MOVD $901, R12 + B callbackasm1(SB) + MOVD $902, R12 + B callbackasm1(SB) + MOVD $903, R12 + B callbackasm1(SB) + MOVD $904, R12 + B callbackasm1(SB) + MOVD $905, R12 + B callbackasm1(SB) + MOVD $906, R12 + B callbackasm1(SB) + MOVD $907, R12 + B callbackasm1(SB) + MOVD $908, R12 + B callbackasm1(SB) + MOVD $909, R12 + B callbackasm1(SB) + MOVD $910, R12 + B callbackasm1(SB) + MOVD $911, R12 + B callbackasm1(SB) + MOVD $912, R12 + B callbackasm1(SB) + MOVD $913, R12 + B callbackasm1(SB) + MOVD $914, R12 + B callbackasm1(SB) + MOVD $915, R12 + B callbackasm1(SB) + MOVD $916, R12 + B callbackasm1(SB) + MOVD $917, R12 + B callbackasm1(SB) + MOVD $918, R12 + B callbackasm1(SB) + MOVD $919, R12 + B callbackasm1(SB) + MOVD $920, R12 + B callbackasm1(SB) + MOVD $921, R12 + B callbackasm1(SB) + MOVD $922, R12 + B callbackasm1(SB) + MOVD $923, R12 + B callbackasm1(SB) + MOVD $924, R12 + B callbackasm1(SB) + MOVD $925, R12 + B callbackasm1(SB) + MOVD $926, R12 + B callbackasm1(SB) + MOVD $927, R12 + B callbackasm1(SB) + MOVD $928, R12 + B callbackasm1(SB) + MOVD $929, R12 + B callbackasm1(SB) + MOVD $930, R12 + B callbackasm1(SB) + MOVD $931, R12 + B callbackasm1(SB) + MOVD $932, R12 + B callbackasm1(SB) + MOVD $933, R12 + B callbackasm1(SB) + MOVD $934, R12 + B callbackasm1(SB) + MOVD $935, R12 + B callbackasm1(SB) + MOVD $936, R12 + B callbackasm1(SB) + MOVD $937, R12 + B callbackasm1(SB) + MOVD $938, R12 + B callbackasm1(SB) + MOVD $939, R12 + B callbackasm1(SB) + MOVD $940, R12 + B callbackasm1(SB) + MOVD $941, R12 + B callbackasm1(SB) + MOVD $942, R12 + B callbackasm1(SB) + MOVD $943, R12 + B callbackasm1(SB) + MOVD $944, R12 + B callbackasm1(SB) + MOVD $945, R12 + B callbackasm1(SB) + MOVD $946, R12 + B callbackasm1(SB) + MOVD $947, R12 + B callbackasm1(SB) + MOVD $948, R12 + B callbackasm1(SB) + MOVD $949, R12 + B callbackasm1(SB) + MOVD $950, R12 + B callbackasm1(SB) + MOVD $951, R12 + B callbackasm1(SB) + MOVD $952, R12 + B callbackasm1(SB) + MOVD $953, R12 + B callbackasm1(SB) + MOVD $954, R12 + B callbackasm1(SB) + MOVD $955, R12 + B callbackasm1(SB) + MOVD $956, R12 + B callbackasm1(SB) + MOVD $957, R12 + B callbackasm1(SB) + MOVD $958, R12 + B callbackasm1(SB) + MOVD $959, R12 + B callbackasm1(SB) + MOVD $960, R12 + B callbackasm1(SB) + MOVD $961, R12 + B callbackasm1(SB) + MOVD $962, R12 + B callbackasm1(SB) + MOVD $963, R12 + B callbackasm1(SB) + MOVD $964, R12 + B callbackasm1(SB) + MOVD $965, R12 + B callbackasm1(SB) + MOVD $966, R12 + B callbackasm1(SB) + MOVD $967, R12 + B callbackasm1(SB) + MOVD $968, R12 + B callbackasm1(SB) + MOVD $969, R12 + B callbackasm1(SB) + MOVD $970, R12 + B callbackasm1(SB) + MOVD $971, R12 + B callbackasm1(SB) + MOVD $972, R12 + B callbackasm1(SB) + MOVD $973, R12 + B callbackasm1(SB) + MOVD $974, R12 + B callbackasm1(SB) + MOVD $975, R12 + B callbackasm1(SB) + MOVD $976, R12 + B callbackasm1(SB) + MOVD $977, R12 + B callbackasm1(SB) + MOVD $978, R12 + B callbackasm1(SB) + MOVD $979, R12 + B callbackasm1(SB) + MOVD $980, R12 + B callbackasm1(SB) + MOVD $981, R12 + B callbackasm1(SB) + MOVD $982, R12 + B callbackasm1(SB) + MOVD $983, R12 + B callbackasm1(SB) + MOVD $984, R12 + B callbackasm1(SB) + MOVD $985, R12 + B callbackasm1(SB) + MOVD $986, R12 + B callbackasm1(SB) + MOVD $987, R12 + B callbackasm1(SB) + MOVD $988, R12 + B callbackasm1(SB) + MOVD $989, R12 + B callbackasm1(SB) + MOVD $990, R12 + B callbackasm1(SB) + MOVD $991, R12 + B callbackasm1(SB) + MOVD $992, R12 + B callbackasm1(SB) + MOVD $993, R12 + B callbackasm1(SB) + MOVD $994, R12 + B callbackasm1(SB) + MOVD $995, R12 + B callbackasm1(SB) + MOVD $996, R12 + B callbackasm1(SB) + MOVD $997, R12 + B callbackasm1(SB) + MOVD $998, R12 + B callbackasm1(SB) + MOVD $999, R12 + B callbackasm1(SB) + MOVD $1000, R12 + B callbackasm1(SB) + MOVD $1001, R12 + B callbackasm1(SB) + MOVD $1002, R12 + B callbackasm1(SB) + MOVD $1003, R12 + B callbackasm1(SB) + MOVD $1004, R12 + B callbackasm1(SB) + MOVD $1005, R12 + B callbackasm1(SB) + MOVD $1006, R12 + B callbackasm1(SB) + MOVD $1007, R12 + B callbackasm1(SB) + MOVD $1008, R12 + B callbackasm1(SB) + MOVD $1009, R12 + B callbackasm1(SB) + MOVD $1010, R12 + B callbackasm1(SB) + MOVD $1011, R12 + B callbackasm1(SB) + MOVD $1012, R12 + B callbackasm1(SB) + MOVD $1013, R12 + B callbackasm1(SB) + MOVD $1014, R12 + B callbackasm1(SB) + MOVD $1015, R12 + B callbackasm1(SB) + MOVD $1016, R12 + B callbackasm1(SB) + MOVD $1017, R12 + B callbackasm1(SB) + MOVD $1018, R12 + B callbackasm1(SB) + MOVD $1019, R12 + B callbackasm1(SB) + MOVD $1020, R12 + B callbackasm1(SB) + MOVD $1021, R12 + B callbackasm1(SB) + MOVD $1022, R12 + B callbackasm1(SB) + MOVD $1023, R12 + B callbackasm1(SB) + MOVD $1024, R12 + B callbackasm1(SB) + MOVD $1025, R12 + B callbackasm1(SB) + MOVD $1026, R12 + B callbackasm1(SB) + MOVD $1027, R12 + B callbackasm1(SB) + MOVD $1028, R12 + B callbackasm1(SB) + MOVD $1029, R12 + B callbackasm1(SB) + MOVD $1030, R12 + B callbackasm1(SB) + MOVD $1031, R12 + B callbackasm1(SB) + MOVD $1032, R12 + B callbackasm1(SB) + MOVD $1033, R12 + B callbackasm1(SB) + MOVD $1034, R12 + B callbackasm1(SB) + MOVD $1035, R12 + B callbackasm1(SB) + MOVD $1036, R12 + B callbackasm1(SB) + MOVD $1037, R12 + B callbackasm1(SB) + MOVD $1038, R12 + B callbackasm1(SB) + MOVD $1039, R12 + B callbackasm1(SB) + MOVD $1040, R12 + B callbackasm1(SB) + MOVD $1041, R12 + B callbackasm1(SB) + MOVD $1042, R12 + B callbackasm1(SB) + MOVD $1043, R12 + B callbackasm1(SB) + MOVD $1044, R12 + B callbackasm1(SB) + MOVD $1045, R12 + B callbackasm1(SB) + MOVD $1046, R12 + B callbackasm1(SB) + MOVD $1047, R12 + B callbackasm1(SB) + MOVD $1048, R12 + B callbackasm1(SB) + MOVD $1049, R12 + B callbackasm1(SB) + MOVD $1050, R12 + B callbackasm1(SB) + MOVD $1051, R12 + B callbackasm1(SB) + MOVD $1052, R12 + B callbackasm1(SB) + MOVD $1053, R12 + B callbackasm1(SB) + MOVD $1054, R12 + B callbackasm1(SB) + MOVD $1055, R12 + B callbackasm1(SB) + MOVD $1056, R12 + B callbackasm1(SB) + MOVD $1057, R12 + B callbackasm1(SB) + MOVD $1058, R12 + B callbackasm1(SB) + MOVD $1059, R12 + B callbackasm1(SB) + MOVD $1060, R12 + B callbackasm1(SB) + MOVD $1061, R12 + B callbackasm1(SB) + MOVD $1062, R12 + B callbackasm1(SB) + MOVD $1063, R12 + B callbackasm1(SB) + MOVD $1064, R12 + B callbackasm1(SB) + MOVD $1065, R12 + B callbackasm1(SB) + MOVD $1066, R12 + B callbackasm1(SB) + MOVD $1067, R12 + B callbackasm1(SB) + MOVD $1068, R12 + B callbackasm1(SB) + MOVD $1069, R12 + B callbackasm1(SB) + MOVD $1070, R12 + B callbackasm1(SB) + MOVD $1071, R12 + B callbackasm1(SB) + MOVD $1072, R12 + B callbackasm1(SB) + MOVD $1073, R12 + B callbackasm1(SB) + MOVD $1074, R12 + B callbackasm1(SB) + MOVD $1075, R12 + B callbackasm1(SB) + MOVD $1076, R12 + B callbackasm1(SB) + MOVD $1077, R12 + B callbackasm1(SB) + MOVD $1078, R12 + B callbackasm1(SB) + MOVD $1079, R12 + B callbackasm1(SB) + MOVD $1080, R12 + B callbackasm1(SB) + MOVD $1081, R12 + B callbackasm1(SB) + MOVD $1082, R12 + B callbackasm1(SB) + MOVD $1083, R12 + B callbackasm1(SB) + MOVD $1084, R12 + B callbackasm1(SB) + MOVD $1085, R12 + B callbackasm1(SB) + MOVD $1086, R12 + B callbackasm1(SB) + MOVD $1087, R12 + B callbackasm1(SB) + MOVD $1088, R12 + B callbackasm1(SB) + MOVD $1089, R12 + B callbackasm1(SB) + MOVD $1090, R12 + B callbackasm1(SB) + MOVD $1091, R12 + B callbackasm1(SB) + MOVD $1092, R12 + B callbackasm1(SB) + MOVD $1093, R12 + B callbackasm1(SB) + MOVD $1094, R12 + B callbackasm1(SB) + MOVD $1095, R12 + B callbackasm1(SB) + MOVD $1096, R12 + B callbackasm1(SB) + MOVD $1097, R12 + B callbackasm1(SB) + MOVD $1098, R12 + B callbackasm1(SB) + MOVD $1099, R12 + B callbackasm1(SB) + MOVD $1100, R12 + B callbackasm1(SB) + MOVD $1101, R12 + B callbackasm1(SB) + MOVD $1102, R12 + B callbackasm1(SB) + MOVD $1103, R12 + B callbackasm1(SB) + MOVD $1104, R12 + B callbackasm1(SB) + MOVD $1105, R12 + B callbackasm1(SB) + MOVD $1106, R12 + B callbackasm1(SB) + MOVD $1107, R12 + B callbackasm1(SB) + MOVD $1108, R12 + B callbackasm1(SB) + MOVD $1109, R12 + B callbackasm1(SB) + MOVD $1110, R12 + B callbackasm1(SB) + MOVD $1111, R12 + B callbackasm1(SB) + MOVD $1112, R12 + B callbackasm1(SB) + MOVD $1113, R12 + B callbackasm1(SB) + MOVD $1114, R12 + B callbackasm1(SB) + MOVD $1115, R12 + B callbackasm1(SB) + MOVD $1116, R12 + B callbackasm1(SB) + MOVD $1117, R12 + B callbackasm1(SB) + MOVD $1118, R12 + B callbackasm1(SB) + MOVD $1119, R12 + B callbackasm1(SB) + MOVD $1120, R12 + B callbackasm1(SB) + MOVD $1121, R12 + B callbackasm1(SB) + MOVD $1122, R12 + B callbackasm1(SB) + MOVD $1123, R12 + B callbackasm1(SB) + MOVD $1124, R12 + B callbackasm1(SB) + MOVD $1125, R12 + B callbackasm1(SB) + MOVD $1126, R12 + B callbackasm1(SB) + MOVD $1127, R12 + B callbackasm1(SB) + MOVD $1128, R12 + B callbackasm1(SB) + MOVD $1129, R12 + B callbackasm1(SB) + MOVD $1130, R12 + B callbackasm1(SB) + MOVD $1131, R12 + B callbackasm1(SB) + MOVD $1132, R12 + B callbackasm1(SB) + MOVD $1133, R12 + B callbackasm1(SB) + MOVD $1134, R12 + B callbackasm1(SB) + MOVD $1135, R12 + B callbackasm1(SB) + MOVD $1136, R12 + B callbackasm1(SB) + MOVD $1137, R12 + B callbackasm1(SB) + MOVD $1138, R12 + B callbackasm1(SB) + MOVD $1139, R12 + B callbackasm1(SB) + MOVD $1140, R12 + B callbackasm1(SB) + MOVD $1141, R12 + B callbackasm1(SB) + MOVD $1142, R12 + B callbackasm1(SB) + MOVD $1143, R12 + B callbackasm1(SB) + MOVD $1144, R12 + B callbackasm1(SB) + MOVD $1145, R12 + B callbackasm1(SB) + MOVD $1146, R12 + B callbackasm1(SB) + MOVD $1147, R12 + B callbackasm1(SB) + MOVD $1148, R12 + B callbackasm1(SB) + MOVD $1149, R12 + B callbackasm1(SB) + MOVD $1150, R12 + B callbackasm1(SB) + MOVD $1151, R12 + B callbackasm1(SB) + MOVD $1152, R12 + B callbackasm1(SB) + MOVD $1153, R12 + B callbackasm1(SB) + MOVD $1154, R12 + B callbackasm1(SB) + MOVD $1155, R12 + B callbackasm1(SB) + MOVD $1156, R12 + B callbackasm1(SB) + MOVD $1157, R12 + B callbackasm1(SB) + MOVD $1158, R12 + B callbackasm1(SB) + MOVD $1159, R12 + B callbackasm1(SB) + MOVD $1160, R12 + B callbackasm1(SB) + MOVD $1161, R12 + B callbackasm1(SB) + MOVD $1162, R12 + B callbackasm1(SB) + MOVD $1163, R12 + B callbackasm1(SB) + MOVD $1164, R12 + B callbackasm1(SB) + MOVD $1165, R12 + B callbackasm1(SB) + MOVD $1166, R12 + B callbackasm1(SB) + MOVD $1167, R12 + B callbackasm1(SB) + MOVD $1168, R12 + B callbackasm1(SB) + MOVD $1169, R12 + B callbackasm1(SB) + MOVD $1170, R12 + B callbackasm1(SB) + MOVD $1171, R12 + B callbackasm1(SB) + MOVD $1172, R12 + B callbackasm1(SB) + MOVD $1173, R12 + B callbackasm1(SB) + MOVD $1174, R12 + B callbackasm1(SB) + MOVD $1175, R12 + B callbackasm1(SB) + MOVD $1176, R12 + B callbackasm1(SB) + MOVD $1177, R12 + B callbackasm1(SB) + MOVD $1178, R12 + B callbackasm1(SB) + MOVD $1179, R12 + B callbackasm1(SB) + MOVD $1180, R12 + B callbackasm1(SB) + MOVD $1181, R12 + B callbackasm1(SB) + MOVD $1182, R12 + B callbackasm1(SB) + MOVD $1183, R12 + B callbackasm1(SB) + MOVD $1184, R12 + B callbackasm1(SB) + MOVD $1185, R12 + B callbackasm1(SB) + MOVD $1186, R12 + B callbackasm1(SB) + MOVD $1187, R12 + B callbackasm1(SB) + MOVD $1188, R12 + B callbackasm1(SB) + MOVD $1189, R12 + B callbackasm1(SB) + MOVD $1190, R12 + B callbackasm1(SB) + MOVD $1191, R12 + B callbackasm1(SB) + MOVD $1192, R12 + B callbackasm1(SB) + MOVD $1193, R12 + B callbackasm1(SB) + MOVD $1194, R12 + B callbackasm1(SB) + MOVD $1195, R12 + B callbackasm1(SB) + MOVD $1196, R12 + B callbackasm1(SB) + MOVD $1197, R12 + B callbackasm1(SB) + MOVD $1198, R12 + B callbackasm1(SB) + MOVD $1199, R12 + B callbackasm1(SB) + MOVD $1200, R12 + B callbackasm1(SB) + MOVD $1201, R12 + B callbackasm1(SB) + MOVD $1202, R12 + B callbackasm1(SB) + MOVD $1203, R12 + B callbackasm1(SB) + MOVD $1204, R12 + B callbackasm1(SB) + MOVD $1205, R12 + B callbackasm1(SB) + MOVD $1206, R12 + B callbackasm1(SB) + MOVD $1207, R12 + B callbackasm1(SB) + MOVD $1208, R12 + B callbackasm1(SB) + MOVD $1209, R12 + B callbackasm1(SB) + MOVD $1210, R12 + B callbackasm1(SB) + MOVD $1211, R12 + B callbackasm1(SB) + MOVD $1212, R12 + B callbackasm1(SB) + MOVD $1213, R12 + B callbackasm1(SB) + MOVD $1214, R12 + B callbackasm1(SB) + MOVD $1215, R12 + B callbackasm1(SB) + MOVD $1216, R12 + B callbackasm1(SB) + MOVD $1217, R12 + B callbackasm1(SB) + MOVD $1218, R12 + B callbackasm1(SB) + MOVD $1219, R12 + B callbackasm1(SB) + MOVD $1220, R12 + B callbackasm1(SB) + MOVD $1221, R12 + B callbackasm1(SB) + MOVD $1222, R12 + B callbackasm1(SB) + MOVD $1223, R12 + B callbackasm1(SB) + MOVD $1224, R12 + B callbackasm1(SB) + MOVD $1225, R12 + B callbackasm1(SB) + MOVD $1226, R12 + B callbackasm1(SB) + MOVD $1227, R12 + B callbackasm1(SB) + MOVD $1228, R12 + B callbackasm1(SB) + MOVD $1229, R12 + B callbackasm1(SB) + MOVD $1230, R12 + B callbackasm1(SB) + MOVD $1231, R12 + B callbackasm1(SB) + MOVD $1232, R12 + B callbackasm1(SB) + MOVD $1233, R12 + B callbackasm1(SB) + MOVD $1234, R12 + B callbackasm1(SB) + MOVD $1235, R12 + B callbackasm1(SB) + MOVD $1236, R12 + B callbackasm1(SB) + MOVD $1237, R12 + B callbackasm1(SB) + MOVD $1238, R12 + B callbackasm1(SB) + MOVD $1239, R12 + B callbackasm1(SB) + MOVD $1240, R12 + B callbackasm1(SB) + MOVD $1241, R12 + B callbackasm1(SB) + MOVD $1242, R12 + B callbackasm1(SB) + MOVD $1243, R12 + B callbackasm1(SB) + MOVD $1244, R12 + B callbackasm1(SB) + MOVD $1245, R12 + B callbackasm1(SB) + MOVD $1246, R12 + B callbackasm1(SB) + MOVD $1247, R12 + B callbackasm1(SB) + MOVD $1248, R12 + B callbackasm1(SB) + MOVD $1249, R12 + B callbackasm1(SB) + MOVD $1250, R12 + B callbackasm1(SB) + MOVD $1251, R12 + B callbackasm1(SB) + MOVD $1252, R12 + B callbackasm1(SB) + MOVD $1253, R12 + B callbackasm1(SB) + MOVD $1254, R12 + B callbackasm1(SB) + MOVD $1255, R12 + B callbackasm1(SB) + MOVD $1256, R12 + B callbackasm1(SB) + MOVD $1257, R12 + B callbackasm1(SB) + MOVD $1258, R12 + B callbackasm1(SB) + MOVD $1259, R12 + B callbackasm1(SB) + MOVD $1260, R12 + B callbackasm1(SB) + MOVD $1261, R12 + B callbackasm1(SB) + MOVD $1262, R12 + B callbackasm1(SB) + MOVD $1263, R12 + B callbackasm1(SB) + MOVD $1264, R12 + B callbackasm1(SB) + MOVD $1265, R12 + B callbackasm1(SB) + MOVD $1266, R12 + B callbackasm1(SB) + MOVD $1267, R12 + B callbackasm1(SB) + MOVD $1268, R12 + B callbackasm1(SB) + MOVD $1269, R12 + B callbackasm1(SB) + MOVD $1270, R12 + B callbackasm1(SB) + MOVD $1271, R12 + B callbackasm1(SB) + MOVD $1272, R12 + B callbackasm1(SB) + MOVD $1273, R12 + B callbackasm1(SB) + MOVD $1274, R12 + B callbackasm1(SB) + MOVD $1275, R12 + B callbackasm1(SB) + MOVD $1276, R12 + B callbackasm1(SB) + MOVD $1277, R12 + B callbackasm1(SB) + MOVD $1278, R12 + B callbackasm1(SB) + MOVD $1279, R12 + B callbackasm1(SB) + MOVD $1280, R12 + B callbackasm1(SB) + MOVD $1281, R12 + B callbackasm1(SB) + MOVD $1282, R12 + B callbackasm1(SB) + MOVD $1283, R12 + B callbackasm1(SB) + MOVD $1284, R12 + B callbackasm1(SB) + MOVD $1285, R12 + B callbackasm1(SB) + MOVD $1286, R12 + B callbackasm1(SB) + MOVD $1287, R12 + B callbackasm1(SB) + MOVD $1288, R12 + B callbackasm1(SB) + MOVD $1289, R12 + B callbackasm1(SB) + MOVD $1290, R12 + B callbackasm1(SB) + MOVD $1291, R12 + B callbackasm1(SB) + MOVD $1292, R12 + B callbackasm1(SB) + MOVD $1293, R12 + B callbackasm1(SB) + MOVD $1294, R12 + B callbackasm1(SB) + MOVD $1295, R12 + B callbackasm1(SB) + MOVD $1296, R12 + B callbackasm1(SB) + MOVD $1297, R12 + B callbackasm1(SB) + MOVD $1298, R12 + B callbackasm1(SB) + MOVD $1299, R12 + B callbackasm1(SB) + MOVD $1300, R12 + B callbackasm1(SB) + MOVD $1301, R12 + B callbackasm1(SB) + MOVD $1302, R12 + B callbackasm1(SB) + MOVD $1303, R12 + B callbackasm1(SB) + MOVD $1304, R12 + B callbackasm1(SB) + MOVD $1305, R12 + B callbackasm1(SB) + MOVD $1306, R12 + B callbackasm1(SB) + MOVD $1307, R12 + B callbackasm1(SB) + MOVD $1308, R12 + B callbackasm1(SB) + MOVD $1309, R12 + B callbackasm1(SB) + MOVD $1310, R12 + B callbackasm1(SB) + MOVD $1311, R12 + B callbackasm1(SB) + MOVD $1312, R12 + B callbackasm1(SB) + MOVD $1313, R12 + B callbackasm1(SB) + MOVD $1314, R12 + B callbackasm1(SB) + MOVD $1315, R12 + B callbackasm1(SB) + MOVD $1316, R12 + B callbackasm1(SB) + MOVD $1317, R12 + B callbackasm1(SB) + MOVD $1318, R12 + B callbackasm1(SB) + MOVD $1319, R12 + B callbackasm1(SB) + MOVD $1320, R12 + B callbackasm1(SB) + MOVD $1321, R12 + B callbackasm1(SB) + MOVD $1322, R12 + B callbackasm1(SB) + MOVD $1323, R12 + B callbackasm1(SB) + MOVD $1324, R12 + B callbackasm1(SB) + MOVD $1325, R12 + B callbackasm1(SB) + MOVD $1326, R12 + B callbackasm1(SB) + MOVD $1327, R12 + B callbackasm1(SB) + MOVD $1328, R12 + B callbackasm1(SB) + MOVD $1329, R12 + B callbackasm1(SB) + MOVD $1330, R12 + B callbackasm1(SB) + MOVD $1331, R12 + B callbackasm1(SB) + MOVD $1332, R12 + B callbackasm1(SB) + MOVD $1333, R12 + B callbackasm1(SB) + MOVD $1334, R12 + B callbackasm1(SB) + MOVD $1335, R12 + B callbackasm1(SB) + MOVD $1336, R12 + B callbackasm1(SB) + MOVD $1337, R12 + B callbackasm1(SB) + MOVD $1338, R12 + B callbackasm1(SB) + MOVD $1339, R12 + B callbackasm1(SB) + MOVD $1340, R12 + B callbackasm1(SB) + MOVD $1341, R12 + B callbackasm1(SB) + MOVD $1342, R12 + B callbackasm1(SB) + MOVD $1343, R12 + B callbackasm1(SB) + MOVD $1344, R12 + B callbackasm1(SB) + MOVD $1345, R12 + B callbackasm1(SB) + MOVD $1346, R12 + B callbackasm1(SB) + MOVD $1347, R12 + B callbackasm1(SB) + MOVD $1348, R12 + B callbackasm1(SB) + MOVD $1349, R12 + B callbackasm1(SB) + MOVD $1350, R12 + B callbackasm1(SB) + MOVD $1351, R12 + B callbackasm1(SB) + MOVD $1352, R12 + B callbackasm1(SB) + MOVD $1353, R12 + B callbackasm1(SB) + MOVD $1354, R12 + B callbackasm1(SB) + MOVD $1355, R12 + B callbackasm1(SB) + MOVD $1356, R12 + B callbackasm1(SB) + MOVD $1357, R12 + B callbackasm1(SB) + MOVD $1358, R12 + B callbackasm1(SB) + MOVD $1359, R12 + B callbackasm1(SB) + MOVD $1360, R12 + B callbackasm1(SB) + MOVD $1361, R12 + B callbackasm1(SB) + MOVD $1362, R12 + B callbackasm1(SB) + MOVD $1363, R12 + B callbackasm1(SB) + MOVD $1364, R12 + B callbackasm1(SB) + MOVD $1365, R12 + B callbackasm1(SB) + MOVD $1366, R12 + B callbackasm1(SB) + MOVD $1367, R12 + B callbackasm1(SB) + MOVD $1368, R12 + B callbackasm1(SB) + MOVD $1369, R12 + B callbackasm1(SB) + MOVD $1370, R12 + B callbackasm1(SB) + MOVD $1371, R12 + B callbackasm1(SB) + MOVD $1372, R12 + B callbackasm1(SB) + MOVD $1373, R12 + B callbackasm1(SB) + MOVD $1374, R12 + B callbackasm1(SB) + MOVD $1375, R12 + B callbackasm1(SB) + MOVD $1376, R12 + B callbackasm1(SB) + MOVD $1377, R12 + B callbackasm1(SB) + MOVD $1378, R12 + B callbackasm1(SB) + MOVD $1379, R12 + B callbackasm1(SB) + MOVD $1380, R12 + B callbackasm1(SB) + MOVD $1381, R12 + B callbackasm1(SB) + MOVD $1382, R12 + B callbackasm1(SB) + MOVD $1383, R12 + B callbackasm1(SB) + MOVD $1384, R12 + B callbackasm1(SB) + MOVD $1385, R12 + B callbackasm1(SB) + MOVD $1386, R12 + B callbackasm1(SB) + MOVD $1387, R12 + B callbackasm1(SB) + MOVD $1388, R12 + B callbackasm1(SB) + MOVD $1389, R12 + B callbackasm1(SB) + MOVD $1390, R12 + B callbackasm1(SB) + MOVD $1391, R12 + B callbackasm1(SB) + MOVD $1392, R12 + B callbackasm1(SB) + MOVD $1393, R12 + B callbackasm1(SB) + MOVD $1394, R12 + B callbackasm1(SB) + MOVD $1395, R12 + B callbackasm1(SB) + MOVD $1396, R12 + B callbackasm1(SB) + MOVD $1397, R12 + B callbackasm1(SB) + MOVD $1398, R12 + B callbackasm1(SB) + MOVD $1399, R12 + B callbackasm1(SB) + MOVD $1400, R12 + B callbackasm1(SB) + MOVD $1401, R12 + B callbackasm1(SB) + MOVD $1402, R12 + B callbackasm1(SB) + MOVD $1403, R12 + B callbackasm1(SB) + MOVD $1404, R12 + B callbackasm1(SB) + MOVD $1405, R12 + B callbackasm1(SB) + MOVD $1406, R12 + B callbackasm1(SB) + MOVD $1407, R12 + B callbackasm1(SB) + MOVD $1408, R12 + B callbackasm1(SB) + MOVD $1409, R12 + B callbackasm1(SB) + MOVD $1410, R12 + B callbackasm1(SB) + MOVD $1411, R12 + B callbackasm1(SB) + MOVD $1412, R12 + B callbackasm1(SB) + MOVD $1413, R12 + B callbackasm1(SB) + MOVD $1414, R12 + B callbackasm1(SB) + MOVD $1415, R12 + B callbackasm1(SB) + MOVD $1416, R12 + B callbackasm1(SB) + MOVD $1417, R12 + B callbackasm1(SB) + MOVD $1418, R12 + B callbackasm1(SB) + MOVD $1419, R12 + B callbackasm1(SB) + MOVD $1420, R12 + B callbackasm1(SB) + MOVD $1421, R12 + B callbackasm1(SB) + MOVD $1422, R12 + B callbackasm1(SB) + MOVD $1423, R12 + B callbackasm1(SB) + MOVD $1424, R12 + B callbackasm1(SB) + MOVD $1425, R12 + B callbackasm1(SB) + MOVD $1426, R12 + B callbackasm1(SB) + MOVD $1427, R12 + B callbackasm1(SB) + MOVD $1428, R12 + B callbackasm1(SB) + MOVD $1429, R12 + B callbackasm1(SB) + MOVD $1430, R12 + B callbackasm1(SB) + MOVD $1431, R12 + B callbackasm1(SB) + MOVD $1432, R12 + B callbackasm1(SB) + MOVD $1433, R12 + B callbackasm1(SB) + MOVD $1434, R12 + B callbackasm1(SB) + MOVD $1435, R12 + B callbackasm1(SB) + MOVD $1436, R12 + B callbackasm1(SB) + MOVD $1437, R12 + B callbackasm1(SB) + MOVD $1438, R12 + B callbackasm1(SB) + MOVD $1439, R12 + B callbackasm1(SB) + MOVD $1440, R12 + B callbackasm1(SB) + MOVD $1441, R12 + B callbackasm1(SB) + MOVD $1442, R12 + B callbackasm1(SB) + MOVD $1443, R12 + B callbackasm1(SB) + MOVD $1444, R12 + B callbackasm1(SB) + MOVD $1445, R12 + B callbackasm1(SB) + MOVD $1446, R12 + B callbackasm1(SB) + MOVD $1447, R12 + B callbackasm1(SB) + MOVD $1448, R12 + B callbackasm1(SB) + MOVD $1449, R12 + B callbackasm1(SB) + MOVD $1450, R12 + B callbackasm1(SB) + MOVD $1451, R12 + B callbackasm1(SB) + MOVD $1452, R12 + B callbackasm1(SB) + MOVD $1453, R12 + B callbackasm1(SB) + MOVD $1454, R12 + B callbackasm1(SB) + MOVD $1455, R12 + B callbackasm1(SB) + MOVD $1456, R12 + B callbackasm1(SB) + MOVD $1457, R12 + B callbackasm1(SB) + MOVD $1458, R12 + B callbackasm1(SB) + MOVD $1459, R12 + B callbackasm1(SB) + MOVD $1460, R12 + B callbackasm1(SB) + MOVD $1461, R12 + B callbackasm1(SB) + MOVD $1462, R12 + B callbackasm1(SB) + MOVD $1463, R12 + B callbackasm1(SB) + MOVD $1464, R12 + B callbackasm1(SB) + MOVD $1465, R12 + B callbackasm1(SB) + MOVD $1466, R12 + B callbackasm1(SB) + MOVD $1467, R12 + B callbackasm1(SB) + MOVD $1468, R12 + B callbackasm1(SB) + MOVD $1469, R12 + B callbackasm1(SB) + MOVD $1470, R12 + B callbackasm1(SB) + MOVD $1471, R12 + B callbackasm1(SB) + MOVD $1472, R12 + B callbackasm1(SB) + MOVD $1473, R12 + B callbackasm1(SB) + MOVD $1474, R12 + B callbackasm1(SB) + MOVD $1475, R12 + B callbackasm1(SB) + MOVD $1476, R12 + B callbackasm1(SB) + MOVD $1477, R12 + B callbackasm1(SB) + MOVD $1478, R12 + B callbackasm1(SB) + MOVD $1479, R12 + B callbackasm1(SB) + MOVD $1480, R12 + B callbackasm1(SB) + MOVD $1481, R12 + B callbackasm1(SB) + MOVD $1482, R12 + B callbackasm1(SB) + MOVD $1483, R12 + B callbackasm1(SB) + MOVD $1484, R12 + B callbackasm1(SB) + MOVD $1485, R12 + B callbackasm1(SB) + MOVD $1486, R12 + B callbackasm1(SB) + MOVD $1487, R12 + B callbackasm1(SB) + MOVD $1488, R12 + B callbackasm1(SB) + MOVD $1489, R12 + B callbackasm1(SB) + MOVD $1490, R12 + B callbackasm1(SB) + MOVD $1491, R12 + B callbackasm1(SB) + MOVD $1492, R12 + B callbackasm1(SB) + MOVD $1493, R12 + B callbackasm1(SB) + MOVD $1494, R12 + B callbackasm1(SB) + MOVD $1495, R12 + B callbackasm1(SB) + MOVD $1496, R12 + B callbackasm1(SB) + MOVD $1497, R12 + B callbackasm1(SB) + MOVD $1498, R12 + B callbackasm1(SB) + MOVD $1499, R12 + B callbackasm1(SB) + MOVD $1500, R12 + B callbackasm1(SB) + MOVD $1501, R12 + B callbackasm1(SB) + MOVD $1502, R12 + B callbackasm1(SB) + MOVD $1503, R12 + B callbackasm1(SB) + MOVD $1504, R12 + B callbackasm1(SB) + MOVD $1505, R12 + B callbackasm1(SB) + MOVD $1506, R12 + B callbackasm1(SB) + MOVD $1507, R12 + B callbackasm1(SB) + MOVD $1508, R12 + B callbackasm1(SB) + MOVD $1509, R12 + B callbackasm1(SB) + MOVD $1510, R12 + B callbackasm1(SB) + MOVD $1511, R12 + B callbackasm1(SB) + MOVD $1512, R12 + B callbackasm1(SB) + MOVD $1513, R12 + B callbackasm1(SB) + MOVD $1514, R12 + B callbackasm1(SB) + MOVD $1515, R12 + B callbackasm1(SB) + MOVD $1516, R12 + B callbackasm1(SB) + MOVD $1517, R12 + B callbackasm1(SB) + MOVD $1518, R12 + B callbackasm1(SB) + MOVD $1519, R12 + B callbackasm1(SB) + MOVD $1520, R12 + B callbackasm1(SB) + MOVD $1521, R12 + B callbackasm1(SB) + MOVD $1522, R12 + B callbackasm1(SB) + MOVD $1523, R12 + B callbackasm1(SB) + MOVD $1524, R12 + B callbackasm1(SB) + MOVD $1525, R12 + B callbackasm1(SB) + MOVD $1526, R12 + B callbackasm1(SB) + MOVD $1527, R12 + B callbackasm1(SB) + MOVD $1528, R12 + B callbackasm1(SB) + MOVD $1529, R12 + B callbackasm1(SB) + MOVD $1530, R12 + B callbackasm1(SB) + MOVD $1531, R12 + B callbackasm1(SB) + MOVD $1532, R12 + B callbackasm1(SB) + MOVD $1533, R12 + B callbackasm1(SB) + MOVD $1534, R12 + B callbackasm1(SB) + MOVD $1535, R12 + B callbackasm1(SB) + MOVD $1536, R12 + B callbackasm1(SB) + MOVD $1537, R12 + B callbackasm1(SB) + MOVD $1538, R12 + B callbackasm1(SB) + MOVD $1539, R12 + B callbackasm1(SB) + MOVD $1540, R12 + B callbackasm1(SB) + MOVD $1541, R12 + B callbackasm1(SB) + MOVD $1542, R12 + B callbackasm1(SB) + MOVD $1543, R12 + B callbackasm1(SB) + MOVD $1544, R12 + B callbackasm1(SB) + MOVD $1545, R12 + B callbackasm1(SB) + MOVD $1546, R12 + B callbackasm1(SB) + MOVD $1547, R12 + B callbackasm1(SB) + MOVD $1548, R12 + B callbackasm1(SB) + MOVD $1549, R12 + B callbackasm1(SB) + MOVD $1550, R12 + B callbackasm1(SB) + MOVD $1551, R12 + B callbackasm1(SB) + MOVD $1552, R12 + B callbackasm1(SB) + MOVD $1553, R12 + B callbackasm1(SB) + MOVD $1554, R12 + B callbackasm1(SB) + MOVD $1555, R12 + B callbackasm1(SB) + MOVD $1556, R12 + B callbackasm1(SB) + MOVD $1557, R12 + B callbackasm1(SB) + MOVD $1558, R12 + B callbackasm1(SB) + MOVD $1559, R12 + B callbackasm1(SB) + MOVD $1560, R12 + B callbackasm1(SB) + MOVD $1561, R12 + B callbackasm1(SB) + MOVD $1562, R12 + B callbackasm1(SB) + MOVD $1563, R12 + B callbackasm1(SB) + MOVD $1564, R12 + B callbackasm1(SB) + MOVD $1565, R12 + B callbackasm1(SB) + MOVD $1566, R12 + B callbackasm1(SB) + MOVD $1567, R12 + B callbackasm1(SB) + MOVD $1568, R12 + B callbackasm1(SB) + MOVD $1569, R12 + B callbackasm1(SB) + MOVD $1570, R12 + B callbackasm1(SB) + MOVD $1571, R12 + B callbackasm1(SB) + MOVD $1572, R12 + B callbackasm1(SB) + MOVD $1573, R12 + B callbackasm1(SB) + MOVD $1574, R12 + B callbackasm1(SB) + MOVD $1575, R12 + B callbackasm1(SB) + MOVD $1576, R12 + B callbackasm1(SB) + MOVD $1577, R12 + B callbackasm1(SB) + MOVD $1578, R12 + B callbackasm1(SB) + MOVD $1579, R12 + B callbackasm1(SB) + MOVD $1580, R12 + B callbackasm1(SB) + MOVD $1581, R12 + B callbackasm1(SB) + MOVD $1582, R12 + B callbackasm1(SB) + MOVD $1583, R12 + B callbackasm1(SB) + MOVD $1584, R12 + B callbackasm1(SB) + MOVD $1585, R12 + B callbackasm1(SB) + MOVD $1586, R12 + B callbackasm1(SB) + MOVD $1587, R12 + B callbackasm1(SB) + MOVD $1588, R12 + B callbackasm1(SB) + MOVD $1589, R12 + B callbackasm1(SB) + MOVD $1590, R12 + B callbackasm1(SB) + MOVD $1591, R12 + B callbackasm1(SB) + MOVD $1592, R12 + B callbackasm1(SB) + MOVD $1593, R12 + B callbackasm1(SB) + MOVD $1594, R12 + B callbackasm1(SB) + MOVD $1595, R12 + B callbackasm1(SB) + MOVD $1596, R12 + B callbackasm1(SB) + MOVD $1597, R12 + B callbackasm1(SB) + MOVD $1598, R12 + B callbackasm1(SB) + MOVD $1599, R12 + B callbackasm1(SB) + MOVD $1600, R12 + B callbackasm1(SB) + MOVD $1601, R12 + B callbackasm1(SB) + MOVD $1602, R12 + B callbackasm1(SB) + MOVD $1603, R12 + B callbackasm1(SB) + MOVD $1604, R12 + B callbackasm1(SB) + MOVD $1605, R12 + B callbackasm1(SB) + MOVD $1606, R12 + B callbackasm1(SB) + MOVD $1607, R12 + B callbackasm1(SB) + MOVD $1608, R12 + B callbackasm1(SB) + MOVD $1609, R12 + B callbackasm1(SB) + MOVD $1610, R12 + B callbackasm1(SB) + MOVD $1611, R12 + B callbackasm1(SB) + MOVD $1612, R12 + B callbackasm1(SB) + MOVD $1613, R12 + B callbackasm1(SB) + MOVD $1614, R12 + B callbackasm1(SB) + MOVD $1615, R12 + B callbackasm1(SB) + MOVD $1616, R12 + B callbackasm1(SB) + MOVD $1617, R12 + B callbackasm1(SB) + MOVD $1618, R12 + B callbackasm1(SB) + MOVD $1619, R12 + B callbackasm1(SB) + MOVD $1620, R12 + B callbackasm1(SB) + MOVD $1621, R12 + B callbackasm1(SB) + MOVD $1622, R12 + B callbackasm1(SB) + MOVD $1623, R12 + B callbackasm1(SB) + MOVD $1624, R12 + B callbackasm1(SB) + MOVD $1625, R12 + B callbackasm1(SB) + MOVD $1626, R12 + B callbackasm1(SB) + MOVD $1627, R12 + B callbackasm1(SB) + MOVD $1628, R12 + B callbackasm1(SB) + MOVD $1629, R12 + B callbackasm1(SB) + MOVD $1630, R12 + B callbackasm1(SB) + MOVD $1631, R12 + B callbackasm1(SB) + MOVD $1632, R12 + B callbackasm1(SB) + MOVD $1633, R12 + B callbackasm1(SB) + MOVD $1634, R12 + B callbackasm1(SB) + MOVD $1635, R12 + B callbackasm1(SB) + MOVD $1636, R12 + B callbackasm1(SB) + MOVD $1637, R12 + B callbackasm1(SB) + MOVD $1638, R12 + B callbackasm1(SB) + MOVD $1639, R12 + B callbackasm1(SB) + MOVD $1640, R12 + B callbackasm1(SB) + MOVD $1641, R12 + B callbackasm1(SB) + MOVD $1642, R12 + B callbackasm1(SB) + MOVD $1643, R12 + B callbackasm1(SB) + MOVD $1644, R12 + B callbackasm1(SB) + MOVD $1645, R12 + B callbackasm1(SB) + MOVD $1646, R12 + B callbackasm1(SB) + MOVD $1647, R12 + B callbackasm1(SB) + MOVD $1648, R12 + B callbackasm1(SB) + MOVD $1649, R12 + B callbackasm1(SB) + MOVD $1650, R12 + B callbackasm1(SB) + MOVD $1651, R12 + B callbackasm1(SB) + MOVD $1652, R12 + B callbackasm1(SB) + MOVD $1653, R12 + B callbackasm1(SB) + MOVD $1654, R12 + B callbackasm1(SB) + MOVD $1655, R12 + B callbackasm1(SB) + MOVD $1656, R12 + B callbackasm1(SB) + MOVD $1657, R12 + B callbackasm1(SB) + MOVD $1658, R12 + B callbackasm1(SB) + MOVD $1659, R12 + B callbackasm1(SB) + MOVD $1660, R12 + B callbackasm1(SB) + MOVD $1661, R12 + B callbackasm1(SB) + MOVD $1662, R12 + B callbackasm1(SB) + MOVD $1663, R12 + B callbackasm1(SB) + MOVD $1664, R12 + B callbackasm1(SB) + MOVD $1665, R12 + B callbackasm1(SB) + MOVD $1666, R12 + B callbackasm1(SB) + MOVD $1667, R12 + B callbackasm1(SB) + MOVD $1668, R12 + B callbackasm1(SB) + MOVD $1669, R12 + B callbackasm1(SB) + MOVD $1670, R12 + B callbackasm1(SB) + MOVD $1671, R12 + B callbackasm1(SB) + MOVD $1672, R12 + B callbackasm1(SB) + MOVD $1673, R12 + B callbackasm1(SB) + MOVD $1674, R12 + B callbackasm1(SB) + MOVD $1675, R12 + B callbackasm1(SB) + MOVD $1676, R12 + B callbackasm1(SB) + MOVD $1677, R12 + B callbackasm1(SB) + MOVD $1678, R12 + B callbackasm1(SB) + MOVD $1679, R12 + B callbackasm1(SB) + MOVD $1680, R12 + B callbackasm1(SB) + MOVD $1681, R12 + B callbackasm1(SB) + MOVD $1682, R12 + B callbackasm1(SB) + MOVD $1683, R12 + B callbackasm1(SB) + MOVD $1684, R12 + B callbackasm1(SB) + MOVD $1685, R12 + B callbackasm1(SB) + MOVD $1686, R12 + B callbackasm1(SB) + MOVD $1687, R12 + B callbackasm1(SB) + MOVD $1688, R12 + B callbackasm1(SB) + MOVD $1689, R12 + B callbackasm1(SB) + MOVD $1690, R12 + B callbackasm1(SB) + MOVD $1691, R12 + B callbackasm1(SB) + MOVD $1692, R12 + B callbackasm1(SB) + MOVD $1693, R12 + B callbackasm1(SB) + MOVD $1694, R12 + B callbackasm1(SB) + MOVD $1695, R12 + B callbackasm1(SB) + MOVD $1696, R12 + B callbackasm1(SB) + MOVD $1697, R12 + B callbackasm1(SB) + MOVD $1698, R12 + B callbackasm1(SB) + MOVD $1699, R12 + B callbackasm1(SB) + MOVD $1700, R12 + B callbackasm1(SB) + MOVD $1701, R12 + B callbackasm1(SB) + MOVD $1702, R12 + B callbackasm1(SB) + MOVD $1703, R12 + B callbackasm1(SB) + MOVD $1704, R12 + B callbackasm1(SB) + MOVD $1705, R12 + B callbackasm1(SB) + MOVD $1706, R12 + B callbackasm1(SB) + MOVD $1707, R12 + B callbackasm1(SB) + MOVD $1708, R12 + B callbackasm1(SB) + MOVD $1709, R12 + B callbackasm1(SB) + MOVD $1710, R12 + B callbackasm1(SB) + MOVD $1711, R12 + B callbackasm1(SB) + MOVD $1712, R12 + B callbackasm1(SB) + MOVD $1713, R12 + B callbackasm1(SB) + MOVD $1714, R12 + B callbackasm1(SB) + MOVD $1715, R12 + B callbackasm1(SB) + MOVD $1716, R12 + B callbackasm1(SB) + MOVD $1717, R12 + B callbackasm1(SB) + MOVD $1718, R12 + B callbackasm1(SB) + MOVD $1719, R12 + B callbackasm1(SB) + MOVD $1720, R12 + B callbackasm1(SB) + MOVD $1721, R12 + B callbackasm1(SB) + MOVD $1722, R12 + B callbackasm1(SB) + MOVD $1723, R12 + B callbackasm1(SB) + MOVD $1724, R12 + B callbackasm1(SB) + MOVD $1725, R12 + B callbackasm1(SB) + MOVD $1726, R12 + B callbackasm1(SB) + MOVD $1727, R12 + B callbackasm1(SB) + MOVD $1728, R12 + B callbackasm1(SB) + MOVD $1729, R12 + B callbackasm1(SB) + MOVD $1730, R12 + B callbackasm1(SB) + MOVD $1731, R12 + B callbackasm1(SB) + MOVD $1732, R12 + B callbackasm1(SB) + MOVD $1733, R12 + B callbackasm1(SB) + MOVD $1734, R12 + B callbackasm1(SB) + MOVD $1735, R12 + B callbackasm1(SB) + MOVD $1736, R12 + B callbackasm1(SB) + MOVD $1737, R12 + B callbackasm1(SB) + MOVD $1738, R12 + B callbackasm1(SB) + MOVD $1739, R12 + B callbackasm1(SB) + MOVD $1740, R12 + B callbackasm1(SB) + MOVD $1741, R12 + B callbackasm1(SB) + MOVD $1742, R12 + B callbackasm1(SB) + MOVD $1743, R12 + B callbackasm1(SB) + MOVD $1744, R12 + B callbackasm1(SB) + MOVD $1745, R12 + B callbackasm1(SB) + MOVD $1746, R12 + B callbackasm1(SB) + MOVD $1747, R12 + B callbackasm1(SB) + MOVD $1748, R12 + B callbackasm1(SB) + MOVD $1749, R12 + B callbackasm1(SB) + MOVD $1750, R12 + B callbackasm1(SB) + MOVD $1751, R12 + B callbackasm1(SB) + MOVD $1752, R12 + B callbackasm1(SB) + MOVD $1753, R12 + B callbackasm1(SB) + MOVD $1754, R12 + B callbackasm1(SB) + MOVD $1755, R12 + B callbackasm1(SB) + MOVD $1756, R12 + B callbackasm1(SB) + MOVD $1757, R12 + B callbackasm1(SB) + MOVD $1758, R12 + B callbackasm1(SB) + MOVD $1759, R12 + B callbackasm1(SB) + MOVD $1760, R12 + B callbackasm1(SB) + MOVD $1761, R12 + B callbackasm1(SB) + MOVD $1762, R12 + B callbackasm1(SB) + MOVD $1763, R12 + B callbackasm1(SB) + MOVD $1764, R12 + B callbackasm1(SB) + MOVD $1765, R12 + B callbackasm1(SB) + MOVD $1766, R12 + B callbackasm1(SB) + MOVD $1767, R12 + B callbackasm1(SB) + MOVD $1768, R12 + B callbackasm1(SB) + MOVD $1769, R12 + B callbackasm1(SB) + MOVD $1770, R12 + B callbackasm1(SB) + MOVD $1771, R12 + B callbackasm1(SB) + MOVD $1772, R12 + B callbackasm1(SB) + MOVD $1773, R12 + B callbackasm1(SB) + MOVD $1774, R12 + B callbackasm1(SB) + MOVD $1775, R12 + B callbackasm1(SB) + MOVD $1776, R12 + B callbackasm1(SB) + MOVD $1777, R12 + B callbackasm1(SB) + MOVD $1778, R12 + B callbackasm1(SB) + MOVD $1779, R12 + B callbackasm1(SB) + MOVD $1780, R12 + B callbackasm1(SB) + MOVD $1781, R12 + B callbackasm1(SB) + MOVD $1782, R12 + B callbackasm1(SB) + MOVD $1783, R12 + B callbackasm1(SB) + MOVD $1784, R12 + B callbackasm1(SB) + MOVD $1785, R12 + B callbackasm1(SB) + MOVD $1786, R12 + B callbackasm1(SB) + MOVD $1787, R12 + B callbackasm1(SB) + MOVD $1788, R12 + B callbackasm1(SB) + MOVD $1789, R12 + B callbackasm1(SB) + MOVD $1790, R12 + B callbackasm1(SB) + MOVD $1791, R12 + B callbackasm1(SB) + MOVD $1792, R12 + B callbackasm1(SB) + MOVD $1793, R12 + B callbackasm1(SB) + MOVD $1794, R12 + B callbackasm1(SB) + MOVD $1795, R12 + B callbackasm1(SB) + MOVD $1796, R12 + B callbackasm1(SB) + MOVD $1797, R12 + B callbackasm1(SB) + MOVD $1798, R12 + B callbackasm1(SB) + MOVD $1799, R12 + B callbackasm1(SB) + MOVD $1800, R12 + B callbackasm1(SB) + MOVD $1801, R12 + B callbackasm1(SB) + MOVD $1802, R12 + B callbackasm1(SB) + MOVD $1803, R12 + B callbackasm1(SB) + MOVD $1804, R12 + B callbackasm1(SB) + MOVD $1805, R12 + B callbackasm1(SB) + MOVD $1806, R12 + B callbackasm1(SB) + MOVD $1807, R12 + B callbackasm1(SB) + MOVD $1808, R12 + B callbackasm1(SB) + MOVD $1809, R12 + B callbackasm1(SB) + MOVD $1810, R12 + B callbackasm1(SB) + MOVD $1811, R12 + B callbackasm1(SB) + MOVD $1812, R12 + B callbackasm1(SB) + MOVD $1813, R12 + B callbackasm1(SB) + MOVD $1814, R12 + B callbackasm1(SB) + MOVD $1815, R12 + B callbackasm1(SB) + MOVD $1816, R12 + B callbackasm1(SB) + MOVD $1817, R12 + B callbackasm1(SB) + MOVD $1818, R12 + B callbackasm1(SB) + MOVD $1819, R12 + B callbackasm1(SB) + MOVD $1820, R12 + B callbackasm1(SB) + MOVD $1821, R12 + B callbackasm1(SB) + MOVD $1822, R12 + B callbackasm1(SB) + MOVD $1823, R12 + B callbackasm1(SB) + MOVD $1824, R12 + B callbackasm1(SB) + MOVD $1825, R12 + B callbackasm1(SB) + MOVD $1826, R12 + B callbackasm1(SB) + MOVD $1827, R12 + B callbackasm1(SB) + MOVD $1828, R12 + B callbackasm1(SB) + MOVD $1829, R12 + B callbackasm1(SB) + MOVD $1830, R12 + B callbackasm1(SB) + MOVD $1831, R12 + B callbackasm1(SB) + MOVD $1832, R12 + B callbackasm1(SB) + MOVD $1833, R12 + B callbackasm1(SB) + MOVD $1834, R12 + B callbackasm1(SB) + MOVD $1835, R12 + B callbackasm1(SB) + MOVD $1836, R12 + B callbackasm1(SB) + MOVD $1837, R12 + B callbackasm1(SB) + MOVD $1838, R12 + B callbackasm1(SB) + MOVD $1839, R12 + B callbackasm1(SB) + MOVD $1840, R12 + B callbackasm1(SB) + MOVD $1841, R12 + B callbackasm1(SB) + MOVD $1842, R12 + B callbackasm1(SB) + MOVD $1843, R12 + B callbackasm1(SB) + MOVD $1844, R12 + B callbackasm1(SB) + MOVD $1845, R12 + B callbackasm1(SB) + MOVD $1846, R12 + B callbackasm1(SB) + MOVD $1847, R12 + B callbackasm1(SB) + MOVD $1848, R12 + B callbackasm1(SB) + MOVD $1849, R12 + B callbackasm1(SB) + MOVD $1850, R12 + B callbackasm1(SB) + MOVD $1851, R12 + B callbackasm1(SB) + MOVD $1852, R12 + B callbackasm1(SB) + MOVD $1853, R12 + B callbackasm1(SB) + MOVD $1854, R12 + B callbackasm1(SB) + MOVD $1855, R12 + B callbackasm1(SB) + MOVD $1856, R12 + B callbackasm1(SB) + MOVD $1857, R12 + B callbackasm1(SB) + MOVD $1858, R12 + B callbackasm1(SB) + MOVD $1859, R12 + B callbackasm1(SB) + MOVD $1860, R12 + B callbackasm1(SB) + MOVD $1861, R12 + B callbackasm1(SB) + MOVD $1862, R12 + B callbackasm1(SB) + MOVD $1863, R12 + B callbackasm1(SB) + MOVD $1864, R12 + B callbackasm1(SB) + MOVD $1865, R12 + B callbackasm1(SB) + MOVD $1866, R12 + B callbackasm1(SB) + MOVD $1867, R12 + B callbackasm1(SB) + MOVD $1868, R12 + B callbackasm1(SB) + MOVD $1869, R12 + B callbackasm1(SB) + MOVD $1870, R12 + B callbackasm1(SB) + MOVD $1871, R12 + B callbackasm1(SB) + MOVD $1872, R12 + B callbackasm1(SB) + MOVD $1873, R12 + B callbackasm1(SB) + MOVD $1874, R12 + B callbackasm1(SB) + MOVD $1875, R12 + B callbackasm1(SB) + MOVD $1876, R12 + B callbackasm1(SB) + MOVD $1877, R12 + B callbackasm1(SB) + MOVD $1878, R12 + B callbackasm1(SB) + MOVD $1879, R12 + B callbackasm1(SB) + MOVD $1880, R12 + B callbackasm1(SB) + MOVD $1881, R12 + B callbackasm1(SB) + MOVD $1882, R12 + B callbackasm1(SB) + MOVD $1883, R12 + B callbackasm1(SB) + MOVD $1884, R12 + B callbackasm1(SB) + MOVD $1885, R12 + B callbackasm1(SB) + MOVD $1886, R12 + B callbackasm1(SB) + MOVD $1887, R12 + B callbackasm1(SB) + MOVD $1888, R12 + B callbackasm1(SB) + MOVD $1889, R12 + B callbackasm1(SB) + MOVD $1890, R12 + B callbackasm1(SB) + MOVD $1891, R12 + B callbackasm1(SB) + MOVD $1892, R12 + B callbackasm1(SB) + MOVD $1893, R12 + B callbackasm1(SB) + MOVD $1894, R12 + B callbackasm1(SB) + MOVD $1895, R12 + B callbackasm1(SB) + MOVD $1896, R12 + B callbackasm1(SB) + MOVD $1897, R12 + B callbackasm1(SB) + MOVD $1898, R12 + B callbackasm1(SB) + MOVD $1899, R12 + B callbackasm1(SB) + MOVD $1900, R12 + B callbackasm1(SB) + MOVD $1901, R12 + B callbackasm1(SB) + MOVD $1902, R12 + B callbackasm1(SB) + MOVD $1903, R12 + B callbackasm1(SB) + MOVD $1904, R12 + B callbackasm1(SB) + MOVD $1905, R12 + B callbackasm1(SB) + MOVD $1906, R12 + B callbackasm1(SB) + MOVD $1907, R12 + B callbackasm1(SB) + MOVD $1908, R12 + B callbackasm1(SB) + MOVD $1909, R12 + B callbackasm1(SB) + MOVD $1910, R12 + B callbackasm1(SB) + MOVD $1911, R12 + B callbackasm1(SB) + MOVD $1912, R12 + B callbackasm1(SB) + MOVD $1913, R12 + B callbackasm1(SB) + MOVD $1914, R12 + B callbackasm1(SB) + MOVD $1915, R12 + B callbackasm1(SB) + MOVD $1916, R12 + B callbackasm1(SB) + MOVD $1917, R12 + B callbackasm1(SB) + MOVD $1918, R12 + B callbackasm1(SB) + MOVD $1919, R12 + B callbackasm1(SB) + MOVD $1920, R12 + B callbackasm1(SB) + MOVD $1921, R12 + B callbackasm1(SB) + MOVD $1922, R12 + B callbackasm1(SB) + MOVD $1923, R12 + B callbackasm1(SB) + MOVD $1924, R12 + B callbackasm1(SB) + MOVD $1925, R12 + B callbackasm1(SB) + MOVD $1926, R12 + B callbackasm1(SB) + MOVD $1927, R12 + B callbackasm1(SB) + MOVD $1928, R12 + B callbackasm1(SB) + MOVD $1929, R12 + B callbackasm1(SB) + MOVD $1930, R12 + B callbackasm1(SB) + MOVD $1931, R12 + B callbackasm1(SB) + MOVD $1932, R12 + B callbackasm1(SB) + MOVD $1933, R12 + B callbackasm1(SB) + MOVD $1934, R12 + B callbackasm1(SB) + MOVD $1935, R12 + B callbackasm1(SB) + MOVD $1936, R12 + B callbackasm1(SB) + MOVD $1937, R12 + B callbackasm1(SB) + MOVD $1938, R12 + B callbackasm1(SB) + MOVD $1939, R12 + B callbackasm1(SB) + MOVD $1940, R12 + B callbackasm1(SB) + MOVD $1941, R12 + B callbackasm1(SB) + MOVD $1942, R12 + B callbackasm1(SB) + MOVD $1943, R12 + B callbackasm1(SB) + MOVD $1944, R12 + B callbackasm1(SB) + MOVD $1945, R12 + B callbackasm1(SB) + MOVD $1946, R12 + B callbackasm1(SB) + MOVD $1947, R12 + B callbackasm1(SB) + MOVD $1948, R12 + B callbackasm1(SB) + MOVD $1949, R12 + B callbackasm1(SB) + MOVD $1950, R12 + B callbackasm1(SB) + MOVD $1951, R12 + B callbackasm1(SB) + MOVD $1952, R12 + B callbackasm1(SB) + MOVD $1953, R12 + B callbackasm1(SB) + MOVD $1954, R12 + B callbackasm1(SB) + MOVD $1955, R12 + B callbackasm1(SB) + MOVD $1956, R12 + B callbackasm1(SB) + MOVD $1957, R12 + B callbackasm1(SB) + MOVD $1958, R12 + B callbackasm1(SB) + MOVD $1959, R12 + B callbackasm1(SB) + MOVD $1960, R12 + B callbackasm1(SB) + MOVD $1961, R12 + B callbackasm1(SB) + MOVD $1962, R12 + B callbackasm1(SB) + MOVD $1963, R12 + B callbackasm1(SB) + MOVD $1964, R12 + B callbackasm1(SB) + MOVD $1965, R12 + B callbackasm1(SB) + MOVD $1966, R12 + B callbackasm1(SB) + MOVD $1967, R12 + B callbackasm1(SB) + MOVD $1968, R12 + B callbackasm1(SB) + MOVD $1969, R12 + B callbackasm1(SB) + MOVD $1970, R12 + B callbackasm1(SB) + MOVD $1971, R12 + B callbackasm1(SB) + MOVD $1972, R12 + B callbackasm1(SB) + MOVD $1973, R12 + B callbackasm1(SB) + MOVD $1974, R12 + B callbackasm1(SB) + MOVD $1975, R12 + B callbackasm1(SB) + MOVD $1976, R12 + B callbackasm1(SB) + MOVD $1977, R12 + B callbackasm1(SB) + MOVD $1978, R12 + B callbackasm1(SB) + MOVD $1979, R12 + B callbackasm1(SB) + MOVD $1980, R12 + B callbackasm1(SB) + MOVD $1981, R12 + B callbackasm1(SB) + MOVD $1982, R12 + B callbackasm1(SB) + MOVD $1983, R12 + B callbackasm1(SB) + MOVD $1984, R12 + B callbackasm1(SB) + MOVD $1985, R12 + B callbackasm1(SB) + MOVD $1986, R12 + B callbackasm1(SB) + MOVD $1987, R12 + B callbackasm1(SB) + MOVD $1988, R12 + B callbackasm1(SB) + MOVD $1989, R12 + B callbackasm1(SB) + MOVD $1990, R12 + B callbackasm1(SB) + MOVD $1991, R12 + B callbackasm1(SB) + MOVD $1992, R12 + B callbackasm1(SB) + MOVD $1993, R12 + B callbackasm1(SB) + MOVD $1994, R12 + B callbackasm1(SB) + MOVD $1995, R12 + B callbackasm1(SB) + MOVD $1996, R12 + B callbackasm1(SB) + MOVD $1997, R12 + B callbackasm1(SB) + MOVD $1998, R12 + B callbackasm1(SB) + MOVD $1999, R12 + B callbackasm1(SB) diff --git a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md index 02a73ccfd..5edd5a7ca 100644 --- a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md +++ b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md @@ -1,6 +1,15 @@ # Change history of go-restful -## [v3.10.1] - 2022-11-19 +## [v3.11.0] - 2023-08-19 + +- restored behavior as <= v3.9.0 with option to change path strategy using TrimRightSlashEnabled. + +## [v3.10.2] - 2023-03-09 - DO NOT USE + +- introduced MergePathStrategy to be able to revert behaviour of path concatenation to 3.9.0 + see comment in Readme how to customize this behaviour. + +## [v3.10.1] - 2022-11-19 - DO NOT USE - fix broken 3.10.0 by using path package for joining paths diff --git a/vendor/github.com/emicklei/go-restful/v3/README.md b/vendor/github.com/emicklei/go-restful/v3/README.md index 0625359dc..e3e30080e 100644 --- a/vendor/github.com/emicklei/go-restful/v3/README.md +++ b/vendor/github.com/emicklei/go-restful/v3/README.md @@ -79,7 +79,7 @@ func (u UserResource) findUser(request *restful.Request, response *restful.Respo - Content encoding (gzip,deflate) of request and response payloads - Automatic responses on OPTIONS (using a filter) - Automatic CORS request handling (using a filter) -- API declaration for Swagger UI ([go-restful-openapi](https://github.com/emicklei/go-restful-openapi), see [go-restful-swagger12](https://github.com/emicklei/go-restful-swagger12)) +- API declaration for Swagger UI ([go-restful-openapi](https://github.com/emicklei/go-restful-openapi)) - Panic recovery to produce HTTP 500, customizable using RecoverHandler(...) - Route errors produce HTTP 404/405/406/415 errors, customizable using ServiceErrorHandler(...) - Configurable (trace) logging @@ -96,6 +96,7 @@ There are several hooks to customize the behavior of the go-restful package. - Compression - Encoders for other serializers - Use [jsoniter](https://github.com/json-iterator/go) by building this package using a build tag, e.g. `go build -tags=jsoniter .` +- Use the package variable `TrimRightSlashEnabled` (default true) to control the behavior of matching routes that end with a slash `/` ## Resources @@ -108,4 +109,4 @@ There are several hooks to customize the behavior of the go-restful package. Type ```git shortlog -s``` for a full list of contributors. -© 2012 - 2022, http://ernestmicklei.com. MIT License. Contributions are welcome. +© 2012 - 2023, http://ernestmicklei.com. MIT License. Contributions are welcome. diff --git a/vendor/github.com/emicklei/go-restful/v3/route.go b/vendor/github.com/emicklei/go-restful/v3/route.go index ea05b3da8..306c44be7 100644 --- a/vendor/github.com/emicklei/go-restful/v3/route.go +++ b/vendor/github.com/emicklei/go-restful/v3/route.go @@ -40,7 +40,8 @@ type Route struct { ParameterDocs []*Parameter ResponseErrors map[int]ResponseError DefaultResponse *ResponseError - ReadSample, WriteSample interface{} // structs that model an example request or response payload + ReadSample, WriteSample interface{} // structs that model an example request or response payload + WriteSamples []interface{} // if more than one return types is possible (oneof) then this will contain multiple values // Extra information used to store custom information about the route. Metadata map[string]interface{} @@ -164,7 +165,13 @@ func tokenizePath(path string) []string { if "/" == path { return nil } - return strings.Split(strings.TrimLeft(path, "/"), "/") + if TrimRightSlashEnabled { + // 3.9.0 + return strings.Split(strings.Trim(path, "/"), "/") + } else { + // 3.10.2 + return strings.Split(strings.TrimLeft(path, "/"), "/") + } } // for debugging @@ -177,4 +184,8 @@ func (r *Route) EnableContentEncoding(enabled bool) { r.contentEncodingEnabled = &enabled } -var TrimRightSlashEnabled = false +// TrimRightSlashEnabled controls whether +// - path on route building is using path.Join +// - the path of the incoming request is trimmed of its slash suffux. +// Value of true matches the behavior of <= 3.9.0 +var TrimRightSlashEnabled = true diff --git a/vendor/github.com/emicklei/go-restful/v3/route_builder.go b/vendor/github.com/emicklei/go-restful/v3/route_builder.go index 830ebf148..75168c12e 100644 --- a/vendor/github.com/emicklei/go-restful/v3/route_builder.go +++ b/vendor/github.com/emicklei/go-restful/v3/route_builder.go @@ -31,17 +31,18 @@ type RouteBuilder struct { typeNameHandleFunc TypeNameHandleFunction // required // documentation - doc string - notes string - operation string - readSample, writeSample interface{} - parameters []*Parameter - errorMap map[int]ResponseError - defaultResponse *ResponseError - metadata map[string]interface{} - extensions map[string]interface{} - deprecated bool - contentEncodingEnabled *bool + doc string + notes string + operation string + readSample interface{} + writeSamples []interface{} + parameters []*Parameter + errorMap map[int]ResponseError + defaultResponse *ResponseError + metadata map[string]interface{} + extensions map[string]interface{} + deprecated bool + contentEncodingEnabled *bool } // Do evaluates each argument with the RouteBuilder itself. @@ -135,9 +136,9 @@ func (b RouteBuilder) ParameterNamed(name string) (p *Parameter) { return p } -// Writes tells what resource type will be written as the response payload. Optional. -func (b *RouteBuilder) Writes(sample interface{}) *RouteBuilder { - b.writeSample = sample +// Writes tells which one of the resource types will be written as the response payload. Optional. +func (b *RouteBuilder) Writes(samples ...interface{}) *RouteBuilder { + b.writeSamples = samples // oneof return b } @@ -342,19 +343,29 @@ func (b *RouteBuilder) Build() Route { ResponseErrors: b.errorMap, DefaultResponse: b.defaultResponse, ReadSample: b.readSample, - WriteSample: b.writeSample, + WriteSamples: b.writeSamples, Metadata: b.metadata, Deprecated: b.deprecated, contentEncodingEnabled: b.contentEncodingEnabled, allowedMethodsWithoutContentType: b.allowedMethodsWithoutContentType, } + // set WriteSample if one specified + if len(b.writeSamples) == 1 { + route.WriteSample = b.writeSamples[0] + } route.Extensions = b.extensions route.postBuild() return route } -func concatPath(path1, path2 string) string { - return path.Join(path1, path2) +// merge two paths using the current (package global) merge path strategy. +func concatPath(rootPath, routePath string) string { + + if TrimRightSlashEnabled { + return strings.TrimRight(rootPath, "/") + "/" + strings.TrimLeft(routePath, "/") + } else { + return path.Join(rootPath, routePath) + } } var anonymousFuncCount int32 diff --git a/vendor/github.com/fatih/color/README.md b/vendor/github.com/fatih/color/README.md index 5152bf59b..be82827ca 100644 --- a/vendor/github.com/fatih/color/README.md +++ b/vendor/github.com/fatih/color/README.md @@ -7,7 +7,6 @@ suits you. ![Color](https://user-images.githubusercontent.com/438920/96832689-03b3e000-13f4-11eb-9803-46f4c4de3406.jpg) - ## Install ```bash @@ -124,17 +123,17 @@ fmt.Println("All text will now be bold magenta.") ``` ### Disable/Enable color - + There might be a case where you want to explicitly disable/enable color output. the `go-isatty` package will automatically disable color output for non-tty output streams (for example if the output were piped directly to `less`). The `color` package also disables color output if the [`NO_COLOR`](https://no-color.org) environment -variable is set (regardless of its value). +variable is set to a non-empty string. -`Color` has support to disable/enable colors programatically both globally and +`Color` has support to disable/enable colors programmatically both globally and for single color definitions. For example suppose you have a CLI app and a -`--no-color` bool flag. You can easily disable the color output with: +`-no-color` bool flag. You can easily disable the color output with: ```go var flagNoColor = flag.Bool("no-color", false, "Disable color output") @@ -167,11 +166,10 @@ To output color in GitHub Actions (or other CI systems that support ANSI colors) * Save/Return previous values * Evaluate fmt.Formatter interface - ## Credits - * [Fatih Arslan](https://github.com/fatih) - * Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable) +* [Fatih Arslan](https://github.com/fatih) +* Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable) ## License diff --git a/vendor/github.com/fatih/color/color.go b/vendor/github.com/fatih/color/color.go index 98a60f3c8..889f9e77b 100644 --- a/vendor/github.com/fatih/color/color.go +++ b/vendor/github.com/fatih/color/color.go @@ -19,10 +19,10 @@ var ( // set (regardless of its value). This is a global option and affects all // colors. For more control over each color block use the methods // DisableColor() individually. - NoColor = noColorExists() || os.Getenv("TERM") == "dumb" || + NoColor = noColorIsSet() || os.Getenv("TERM") == "dumb" || (!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd())) - // Output defines the standard output of the print functions. By default + // Output defines the standard output of the print functions. By default, // os.Stdout is used. Output = colorable.NewColorableStdout() @@ -35,10 +35,9 @@ var ( colorsCacheMu sync.Mutex // protects colorsCache ) -// noColorExists returns true if the environment variable NO_COLOR exists. -func noColorExists() bool { - _, exists := os.LookupEnv("NO_COLOR") - return exists +// noColorIsSet returns true if the environment variable NO_COLOR is set to a non-empty string. +func noColorIsSet() bool { + return os.Getenv("NO_COLOR") != "" } // Color defines a custom color object which is defined by SGR parameters. @@ -120,7 +119,7 @@ func New(value ...Attribute) *Color { params: make([]Attribute, 0), } - if noColorExists() { + if noColorIsSet() { c.noColor = boolPtr(true) } @@ -152,7 +151,7 @@ func (c *Color) Set() *Color { return c } - fmt.Fprintf(Output, c.format()) + fmt.Fprint(Output, c.format()) return c } @@ -164,16 +163,21 @@ func (c *Color) unset() { Unset() } -func (c *Color) setWriter(w io.Writer) *Color { +// SetWriter is used to set the SGR sequence with the given io.Writer. This is +// a low-level function, and users should use the higher-level functions, such +// as color.Fprint, color.Print, etc. +func (c *Color) SetWriter(w io.Writer) *Color { if c.isNoColorSet() { return c } - fmt.Fprintf(w, c.format()) + fmt.Fprint(w, c.format()) return c } -func (c *Color) unsetWriter(w io.Writer) { +// UnsetWriter resets all escape attributes and clears the output with the give +// io.Writer. Usually should be called after SetWriter(). +func (c *Color) UnsetWriter(w io.Writer) { if c.isNoColorSet() { return } @@ -192,20 +196,14 @@ func (c *Color) Add(value ...Attribute) *Color { return c } -func (c *Color) prepend(value Attribute) { - c.params = append(c.params, 0) - copy(c.params[1:], c.params[0:]) - c.params[0] = value -} - // Fprint formats using the default formats for its operands and writes to w. // Spaces are added between operands when neither is a string. // It returns the number of bytes written and any write error encountered. // On Windows, users should wrap w with colorable.NewColorable() if w is of // type *os.File. func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) { - c.setWriter(w) - defer c.unsetWriter(w) + c.SetWriter(w) + defer c.UnsetWriter(w) return fmt.Fprint(w, a...) } @@ -227,8 +225,8 @@ func (c *Color) Print(a ...interface{}) (n int, err error) { // On Windows, users should wrap w with colorable.NewColorable() if w is of // type *os.File. func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - c.setWriter(w) - defer c.unsetWriter(w) + c.SetWriter(w) + defer c.UnsetWriter(w) return fmt.Fprintf(w, format, a...) } @@ -248,8 +246,8 @@ func (c *Color) Printf(format string, a ...interface{}) (n int, err error) { // On Windows, users should wrap w with colorable.NewColorable() if w is of // type *os.File. func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - c.setWriter(w) - defer c.unsetWriter(w) + c.SetWriter(w) + defer c.UnsetWriter(w) return fmt.Fprintln(w, a...) } @@ -396,7 +394,7 @@ func (c *Color) DisableColor() { } // EnableColor enables the color output. Use it in conjunction with -// DisableColor(). Otherwise this method has no side effects. +// DisableColor(). Otherwise, this method has no side effects. func (c *Color) EnableColor() { c.noColor = boolPtr(false) } diff --git a/vendor/github.com/fatih/color/color_windows.go b/vendor/github.com/fatih/color/color_windows.go new file mode 100644 index 000000000..be01c558e --- /dev/null +++ b/vendor/github.com/fatih/color/color_windows.go @@ -0,0 +1,19 @@ +package color + +import ( + "os" + + "golang.org/x/sys/windows" +) + +func init() { + // Opt-in for ansi color support for current process. + // https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#output-sequences + var outMode uint32 + out := windows.Handle(os.Stdout.Fd()) + if err := windows.GetConsoleMode(out, &outMode); err != nil { + return + } + outMode |= windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING + _ = windows.SetConsoleMode(out, outMode) +} diff --git a/vendor/github.com/fatih/color/doc.go b/vendor/github.com/fatih/color/doc.go index 04541de78..9491ad541 100644 --- a/vendor/github.com/fatih/color/doc.go +++ b/vendor/github.com/fatih/color/doc.go @@ -5,106 +5,105 @@ that suits you. Use simple and default helper functions with predefined foreground colors: - color.Cyan("Prints text in cyan.") + color.Cyan("Prints text in cyan.") - // a newline will be appended automatically - color.Blue("Prints %s in blue.", "text") + // a newline will be appended automatically + color.Blue("Prints %s in blue.", "text") - // More default foreground colors.. - color.Red("We have red") - color.Yellow("Yellow color too!") - color.Magenta("And many others ..") + // More default foreground colors.. + color.Red("We have red") + color.Yellow("Yellow color too!") + color.Magenta("And many others ..") - // Hi-intensity colors - color.HiGreen("Bright green color.") - color.HiBlack("Bright black means gray..") - color.HiWhite("Shiny white color!") + // Hi-intensity colors + color.HiGreen("Bright green color.") + color.HiBlack("Bright black means gray..") + color.HiWhite("Shiny white color!") -However there are times where custom color mixes are required. Below are some +However, there are times when custom color mixes are required. Below are some examples to create custom color objects and use the print functions of each separate color object. - // Create a new color object - c := color.New(color.FgCyan).Add(color.Underline) - c.Println("Prints cyan text with an underline.") + // Create a new color object + c := color.New(color.FgCyan).Add(color.Underline) + c.Println("Prints cyan text with an underline.") - // Or just add them to New() - d := color.New(color.FgCyan, color.Bold) - d.Printf("This prints bold cyan %s\n", "too!.") + // Or just add them to New() + d := color.New(color.FgCyan, color.Bold) + d.Printf("This prints bold cyan %s\n", "too!.") - // Mix up foreground and background colors, create new mixes! - red := color.New(color.FgRed) + // Mix up foreground and background colors, create new mixes! + red := color.New(color.FgRed) - boldRed := red.Add(color.Bold) - boldRed.Println("This will print text in bold red.") + boldRed := red.Add(color.Bold) + boldRed.Println("This will print text in bold red.") - whiteBackground := red.Add(color.BgWhite) - whiteBackground.Println("Red text with White background.") + whiteBackground := red.Add(color.BgWhite) + whiteBackground.Println("Red text with White background.") - // Use your own io.Writer output - color.New(color.FgBlue).Fprintln(myWriter, "blue color!") + // Use your own io.Writer output + color.New(color.FgBlue).Fprintln(myWriter, "blue color!") - blue := color.New(color.FgBlue) - blue.Fprint(myWriter, "This will print text in blue.") + blue := color.New(color.FgBlue) + blue.Fprint(myWriter, "This will print text in blue.") You can create PrintXxx functions to simplify even more: - // Create a custom print function for convenient - red := color.New(color.FgRed).PrintfFunc() - red("warning") - red("error: %s", err) + // Create a custom print function for convenient + red := color.New(color.FgRed).PrintfFunc() + red("warning") + red("error: %s", err) - // Mix up multiple attributes - notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() - notice("don't forget this...") + // Mix up multiple attributes + notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() + notice("don't forget this...") You can also FprintXxx functions to pass your own io.Writer: - blue := color.New(FgBlue).FprintfFunc() - blue(myWriter, "important notice: %s", stars) - - // Mix up with multiple attributes - success := color.New(color.Bold, color.FgGreen).FprintlnFunc() - success(myWriter, don't forget this...") + blue := color.New(FgBlue).FprintfFunc() + blue(myWriter, "important notice: %s", stars) + // Mix up with multiple attributes + success := color.New(color.Bold, color.FgGreen).FprintlnFunc() + success(myWriter, don't forget this...") Or create SprintXxx functions to mix strings with other non-colorized strings: - yellow := New(FgYellow).SprintFunc() - red := New(FgRed).SprintFunc() + yellow := New(FgYellow).SprintFunc() + red := New(FgRed).SprintFunc() - fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error")) + fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error")) - info := New(FgWhite, BgGreen).SprintFunc() - fmt.Printf("this %s rocks!\n", info("package")) + info := New(FgWhite, BgGreen).SprintFunc() + fmt.Printf("this %s rocks!\n", info("package")) Windows support is enabled by default. All Print functions work as intended. -However only for color.SprintXXX functions, user should use fmt.FprintXXX and +However, only for color.SprintXXX functions, user should use fmt.FprintXXX and set the output to color.Output: - fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) + fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) - info := New(FgWhite, BgGreen).SprintFunc() - fmt.Fprintf(color.Output, "this %s rocks!\n", info("package")) + info := New(FgWhite, BgGreen).SprintFunc() + fmt.Fprintf(color.Output, "this %s rocks!\n", info("package")) Using with existing code is possible. Just use the Set() method to set the standard output to the given parameters. That way a rewrite of an existing code is not required. - // Use handy standard colors. - color.Set(color.FgYellow) + // Use handy standard colors. + color.Set(color.FgYellow) - fmt.Println("Existing text will be now in Yellow") - fmt.Printf("This one %s\n", "too") + fmt.Println("Existing text will be now in Yellow") + fmt.Printf("This one %s\n", "too") - color.Unset() // don't forget to unset + color.Unset() // don't forget to unset - // You can mix up parameters - color.Set(color.FgMagenta, color.Bold) - defer color.Unset() // use it in your function + // You can mix up parameters + color.Set(color.FgMagenta, color.Bold) + defer color.Unset() // use it in your function - fmt.Println("All text will be now bold magenta.") + fmt.Println("All text will be now bold magenta.") There might be a case where you want to disable color output (for example to pipe the standard output of your app to somewhere else). `Color` has support to @@ -112,24 +111,24 @@ disable colors both globally and for single color definition. For example suppose you have a CLI app and a `--no-color` bool flag. You can easily disable the color output with: - var flagNoColor = flag.Bool("no-color", false, "Disable color output") + var flagNoColor = flag.Bool("no-color", false, "Disable color output") - if *flagNoColor { - color.NoColor = true // disables colorized output - } + if *flagNoColor { + color.NoColor = true // disables colorized output + } You can also disable the color by setting the NO_COLOR environment variable to any value. It also has support for single color definitions (local). You can disable/enable color output on the fly: - c := color.New(color.FgCyan) - c.Println("Prints cyan text") + c := color.New(color.FgCyan) + c.Println("Prints cyan text") - c.DisableColor() - c.Println("This is printed without any color") + c.DisableColor() + c.Println("This is printed without any color") - c.EnableColor() - c.Println("This prints again cyan...") + c.EnableColor() + c.Println("This prints again cyan...") */ package color diff --git a/vendor/github.com/fsnotify/fsnotify/.cirrus.yml b/vendor/github.com/fsnotify/fsnotify/.cirrus.yml new file mode 100644 index 000000000..ffc7b992b --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/.cirrus.yml @@ -0,0 +1,13 @@ +freebsd_task: + name: 'FreeBSD' + freebsd_instance: + image_family: freebsd-13-2 + install_script: + - pkg update -f + - pkg install -y go + test_script: + # run tests as user "cirrus" instead of root + - pw useradd cirrus -m + - chown -R cirrus:cirrus . + - FSNOTIFY_BUFFER=4096 sudo --preserve-env=FSNOTIFY_BUFFER -u cirrus go test -parallel 1 -race ./... + - sudo --preserve-env=FSNOTIFY_BUFFER -u cirrus go test -parallel 1 -race ./... diff --git a/vendor/github.com/fsnotify/fsnotify/.gitignore b/vendor/github.com/fsnotify/fsnotify/.gitignore index 1d89d85ce..391cc076b 100644 --- a/vendor/github.com/fsnotify/fsnotify/.gitignore +++ b/vendor/github.com/fsnotify/fsnotify/.gitignore @@ -4,3 +4,4 @@ # Output of go build ./cmd/fsnotify /fsnotify +/fsnotify.exe diff --git a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md b/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md index 77f9593bd..e0e575754 100644 --- a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md +++ b/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md @@ -1,16 +1,87 @@ # Changelog -All notable changes to this project will be documented in this file. +Unreleased +---------- +Nothing yet. -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +1.7.0 - 2023-10-22 +------------------ +This version of fsnotify needs Go 1.17. -## [Unreleased] +### Additions -Nothing yet. +- illumos: add FEN backend to support illumos and Solaris. ([#371]) + +- all: add `NewBufferedWatcher()` to use a buffered channel, which can be useful + in cases where you can't control the kernel buffer and receive a large number + of events in bursts. ([#550], [#572]) + +- all: add `AddWith()`, which is identical to `Add()` but allows passing + options. ([#521]) + +- windows: allow setting the ReadDirectoryChangesW() buffer size with + `fsnotify.WithBufferSize()`; the default of 64K is the highest value that + works on all platforms and is enough for most purposes, but in some cases a + highest buffer is needed. ([#521]) + +### Changes and fixes + +- inotify: remove watcher if a watched path is renamed ([#518]) + + After a rename the reported name wasn't updated, or even an empty string. + Inotify doesn't provide any good facilities to update it, so just remove the + watcher. This is already how it worked on kqueue and FEN. + + On Windows this does work, and remains working. + +- windows: don't listen for file attribute changes ([#520]) + + File attribute changes are sent as `FILE_ACTION_MODIFIED` by the Windows API, + with no way to see if they're a file write or attribute change, so would show + up as a fsnotify.Write event. This is never useful, and could result in many + spurious Write events. + +- windows: return `ErrEventOverflow` if the buffer is full ([#525]) + + Before it would merely return "short read", making it hard to detect this + error. + +- kqueue: make sure events for all files are delivered properly when removing a + watched directory ([#526]) + + Previously they would get sent with `""` (empty string) or `"."` as the path + name. + +- kqueue: don't emit spurious Create events for symbolic links ([#524]) + + The link would get resolved but kqueue would "forget" it already saw the link + itself, resulting on a Create for every Write event for the directory. + +- all: return `ErrClosed` on `Add()` when the watcher is closed ([#516]) + +- other: add `Watcher.Errors` and `Watcher.Events` to the no-op `Watcher` in + `backend_other.go`, making it easier to use on unsupported platforms such as + WASM, AIX, etc. ([#528]) + +- other: use the `backend_other.go` no-op if the `appengine` build tag is set; + Google AppEngine forbids usage of the unsafe package so the inotify backend + won't compile there. -## [1.6.0] - 2022-10-13 +[#371]: https://github.com/fsnotify/fsnotify/pull/371 +[#516]: https://github.com/fsnotify/fsnotify/pull/516 +[#518]: https://github.com/fsnotify/fsnotify/pull/518 +[#520]: https://github.com/fsnotify/fsnotify/pull/520 +[#521]: https://github.com/fsnotify/fsnotify/pull/521 +[#524]: https://github.com/fsnotify/fsnotify/pull/524 +[#525]: https://github.com/fsnotify/fsnotify/pull/525 +[#526]: https://github.com/fsnotify/fsnotify/pull/526 +[#528]: https://github.com/fsnotify/fsnotify/pull/528 +[#537]: https://github.com/fsnotify/fsnotify/pull/537 +[#550]: https://github.com/fsnotify/fsnotify/pull/550 +[#572]: https://github.com/fsnotify/fsnotify/pull/572 +1.6.0 - 2022-10-13 +------------------ This version of fsnotify needs Go 1.16 (this was already the case since 1.5.1, but not documented). It also increases the minimum Linux version to 2.6.32. diff --git a/vendor/github.com/fsnotify/fsnotify/README.md b/vendor/github.com/fsnotify/fsnotify/README.md index d4e6080fe..e480733d1 100644 --- a/vendor/github.com/fsnotify/fsnotify/README.md +++ b/vendor/github.com/fsnotify/fsnotify/README.md @@ -1,29 +1,31 @@ fsnotify is a Go library to provide cross-platform filesystem notifications on -Windows, Linux, macOS, and BSD systems. +Windows, Linux, macOS, BSD, and illumos. -Go 1.16 or newer is required; the full documentation is at +Go 1.17 or newer is required; the full documentation is at https://pkg.go.dev/github.com/fsnotify/fsnotify -**It's best to read the documentation at pkg.go.dev, as it's pinned to the last -released version, whereas this README is for the last development version which -may include additions/changes.** - --- Platform support: -| Adapter | OS | Status | -| --------------------- | ---------------| -------------------------------------------------------------| -| inotify | Linux 2.6.32+ | Supported | -| kqueue | BSD, macOS | Supported | -| ReadDirectoryChangesW | Windows | Supported | -| FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) | -| FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/pull/371) | -| fanotify | Linux 5.9+ | [Maybe](https://github.com/fsnotify/fsnotify/issues/114) | -| USN Journals | Windows | [Maybe](https://github.com/fsnotify/fsnotify/issues/53) | -| Polling | *All* | [Maybe](https://github.com/fsnotify/fsnotify/issues/9) | - -Linux and macOS should include Android and iOS, but these are currently untested. +| Backend | OS | Status | +| :-------------------- | :--------- | :------------------------------------------------------------------------ | +| inotify | Linux | Supported | +| kqueue | BSD, macOS | Supported | +| ReadDirectoryChangesW | Windows | Supported | +| FEN | illumos | Supported | +| fanotify | Linux 5.9+ | [Not yet](https://github.com/fsnotify/fsnotify/issues/114) | +| AHAFS | AIX | [aix branch]; experimental due to lack of maintainer and test environment | +| FSEvents | macOS | [Needs support in x/sys/unix][fsevents] | +| USN Journals | Windows | [Needs support in x/sys/windows][usn] | +| Polling | *All* | [Not yet](https://github.com/fsnotify/fsnotify/issues/9) | + +Linux and illumos should include Android and Solaris, but these are currently +untested. + +[fsevents]: https://github.com/fsnotify/fsnotify/issues/11#issuecomment-1279133120 +[usn]: https://github.com/fsnotify/fsnotify/issues/53#issuecomment-1279829847 +[aix branch]: https://github.com/fsnotify/fsnotify/issues/353#issuecomment-1284590129 Usage ----- @@ -83,20 +85,23 @@ run with: % go run ./cmd/fsnotify +Further detailed documentation can be found in godoc: +https://pkg.go.dev/github.com/fsnotify/fsnotify + FAQ --- ### Will a file still be watched when it's moved to another directory? No, not unless you are watching the location it was moved to. -### Are subdirectories watched too? +### Are subdirectories watched? No, you must add watches for any directory you want to watch (a recursive watcher is on the roadmap: [#18]). [#18]: https://github.com/fsnotify/fsnotify/issues/18 ### Do I have to watch the Error and Event channels in a goroutine? -As of now, yes (you can read both channels in the same goroutine using `select`, -you don't need a separate goroutine for both channels; see the example). +Yes. You can read both channels in the same goroutine using `select` (you don't +need a separate goroutine for both channels; see the example). ### Why don't notifications work with NFS, SMB, FUSE, /proc, or /sys? fsnotify requires support from underlying OS to work. The current NFS and SMB @@ -107,6 +112,32 @@ This could be fixed with a polling watcher ([#9]), but it's not yet implemented. [#9]: https://github.com/fsnotify/fsnotify/issues/9 +### Why do I get many Chmod events? +Some programs may generate a lot of attribute changes; for example Spotlight on +macOS, anti-virus programs, backup applications, and some others are known to do +this. As a rule, it's typically best to ignore Chmod events. They're often not +useful, and tend to cause problems. + +Spotlight indexing on macOS can result in multiple events (see [#15]). A +temporary workaround is to add your folder(s) to the *Spotlight Privacy +settings* until we have a native FSEvents implementation (see [#11]). + +[#11]: https://github.com/fsnotify/fsnotify/issues/11 +[#15]: https://github.com/fsnotify/fsnotify/issues/15 + +### Watching a file doesn't work well +Watching individual files (rather than directories) is generally not recommended +as many programs (especially editors) update files atomically: it will write to +a temporary file which is then moved to to destination, overwriting the original +(or some variant thereof). The watcher on the original file is now lost, as that +no longer exists. + +The upshot of this is that a power failure or crash won't leave a half-written +file. + +Watch the parent directory and use `Event.Name` to filter out files you're not +interested in. There is an example of this in `cmd/fsnotify/file.go`. + Platform-specific notes ----------------------- ### Linux @@ -151,11 +182,3 @@ these platforms. The sysctl variables `kern.maxfiles` and `kern.maxfilesperproc` can be used to control the maximum number of open files. - -### macOS -Spotlight indexing on macOS can result in multiple events (see [#15]). A temporary -workaround is to add your folder(s) to the *Spotlight Privacy settings* until we -have a native FSEvents implementation (see [#11]). - -[#11]: https://github.com/fsnotify/fsnotify/issues/11 -[#15]: https://github.com/fsnotify/fsnotify/issues/15 diff --git a/vendor/github.com/fsnotify/fsnotify/backend_fen.go b/vendor/github.com/fsnotify/fsnotify/backend_fen.go index 1a95ad8e7..28497f1dd 100644 --- a/vendor/github.com/fsnotify/fsnotify/backend_fen.go +++ b/vendor/github.com/fsnotify/fsnotify/backend_fen.go @@ -1,10 +1,19 @@ //go:build solaris // +build solaris +// Note: the documentation on the Watcher type and methods is generated from +// mkdoc.zsh + package fsnotify import ( "errors" + "fmt" + "os" + "path/filepath" + "sync" + + "golang.org/x/sys/unix" ) // Watcher watches a set of paths, delivering events on a channel. @@ -17,9 +26,9 @@ import ( // When a file is removed a Remove event won't be emitted until all file // descriptors are closed, and deletes will always emit a Chmod. For example: // -// fp := os.Open("file") -// os.Remove("file") // Triggers Chmod -// fp.Close() // Triggers Remove +// fp := os.Open("file") +// os.Remove("file") // Triggers Chmod +// fp.Close() // Triggers Remove // // This is the event that inotify sends, so not much can be changed about this. // @@ -33,16 +42,16 @@ import ( // // To increase them you can use sysctl or write the value to the /proc file: // -// # Default values on Linux 5.18 -// sysctl fs.inotify.max_user_watches=124983 -// sysctl fs.inotify.max_user_instances=128 +// # Default values on Linux 5.18 +// sysctl fs.inotify.max_user_watches=124983 +// sysctl fs.inotify.max_user_instances=128 // // To make the changes persist on reboot edit /etc/sysctl.conf or // /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check // your distro's documentation): // -// fs.inotify.max_user_watches=124983 -// fs.inotify.max_user_instances=128 +// fs.inotify.max_user_watches=124983 +// fs.inotify.max_user_instances=128 // // Reaching the limit will result in a "no space left on device" or "too many open // files" error. @@ -58,14 +67,20 @@ import ( // control the maximum number of open files, as well as /etc/login.conf on BSD // systems. // -// # macOS notes +// # Windows notes +// +// Paths can be added as "C:\path\to\dir", but forward slashes +// ("C:/path/to/dir") will also work. // -// Spotlight indexing on macOS can result in multiple events (see [#15]). A -// temporary workaround is to add your folder(s) to the "Spotlight Privacy -// Settings" until we have a native FSEvents implementation (see [#11]). +// When a watched directory is removed it will always send an event for the +// directory itself, but may not send events for all files in that directory. +// Sometimes it will send events for all times, sometimes it will send no +// events, and often only for some files. // -// [#11]: https://github.com/fsnotify/fsnotify/issues/11 -// [#15]: https://github.com/fsnotify/fsnotify/issues/15 +// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest +// value that is guaranteed to work with SMB filesystems. If you have many +// events in quick succession this may not be enough, and you will have to use +// [WithBufferSize] to increase the value. type Watcher struct { // Events sends the filesystem change events. // @@ -92,44 +107,129 @@ type Watcher struct { // initiated by the user may show up as one or multiple // writes, depending on when the system syncs things to // disk. For example when compiling a large Go program - // you may get hundreds of Write events, so you - // probably want to wait until you've stopped receiving - // them (see the dedup example in cmd/fsnotify). + // you may get hundreds of Write events, and you may + // want to wait until you've stopped receiving them + // (see the dedup example in cmd/fsnotify). + // + // Some systems may send Write event for directories + // when the directory content changes. // // fsnotify.Chmod Attributes were changed. On Linux this is also sent // when a file is removed (or more accurately, when a // link to an inode is removed). On kqueue it's sent - // and on kqueue when a file is truncated. On Windows - // it's never sent. + // when a file is truncated. On Windows it's never + // sent. Events chan Event // Errors sends any errors. + // + // ErrEventOverflow is used to indicate there are too many events: + // + // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl) + // - windows: The buffer size is too small; WithBufferSize() can be used to increase it. + // - kqueue, fen: Not used. Errors chan error + + mu sync.Mutex + port *unix.EventPort + done chan struct{} // Channel for sending a "quit message" to the reader goroutine + dirs map[string]struct{} // Explicitly watched directories + watches map[string]struct{} // Explicitly watched non-directories } // NewWatcher creates a new Watcher. func NewWatcher() (*Watcher, error) { - return nil, errors.New("FEN based watcher not yet supported for fsnotify\n") + return NewBufferedWatcher(0) } -// Close removes all watches and closes the events channel. +// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events +// channel. +// +// The main use case for this is situations with a very large number of events +// where the kernel buffer size can't be increased (e.g. due to lack of +// permissions). An unbuffered Watcher will perform better for almost all use +// cases, and whenever possible you will be better off increasing the kernel +// buffers instead of adding a large userspace buffer. +func NewBufferedWatcher(sz uint) (*Watcher, error) { + w := &Watcher{ + Events: make(chan Event, sz), + Errors: make(chan error), + dirs: make(map[string]struct{}), + watches: make(map[string]struct{}), + done: make(chan struct{}), + } + + var err error + w.port, err = unix.NewEventPort() + if err != nil { + return nil, fmt.Errorf("fsnotify.NewWatcher: %w", err) + } + + go w.readEvents() + return w, nil +} + +// sendEvent attempts to send an event to the user, returning true if the event +// was put in the channel successfully and false if the watcher has been closed. +func (w *Watcher) sendEvent(name string, op Op) (sent bool) { + select { + case w.Events <- Event{Name: name, Op: op}: + return true + case <-w.done: + return false + } +} + +// sendError attempts to send an error to the user, returning true if the error +// was put in the channel successfully and false if the watcher has been closed. +func (w *Watcher) sendError(err error) (sent bool) { + select { + case w.Errors <- err: + return true + case <-w.done: + return false + } +} + +func (w *Watcher) isClosed() bool { + select { + case <-w.done: + return true + default: + return false + } +} + +// Close removes all watches and closes the Events channel. func (w *Watcher) Close() error { - return nil + // Take the lock used by associateFile to prevent lingering events from + // being processed after the close + w.mu.Lock() + defer w.mu.Unlock() + if w.isClosed() { + return nil + } + close(w.done) + return w.port.Close() } // Add starts monitoring the path for changes. // -// A path can only be watched once; attempting to watch it more than once will -// return an error. Paths that do not yet exist on the filesystem cannot be -// added. A watch will be automatically removed if the path is deleted. +// A path can only be watched once; watching it more than once is a no-op and will +// not return an error. Paths that do not yet exist on the filesystem cannot be +// watched. // -// A path will remain watched if it gets renamed to somewhere else on the same -// filesystem, but the monitor will get removed if the path gets deleted and -// re-created, or if it's moved to a different filesystem. +// A watch will be automatically removed if the watched path is deleted or +// renamed. The exception is the Windows backend, which doesn't remove the +// watcher on renames. // // Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special // filesystems (/proc, /sys, etc.) generally don't work. // +// Returns [ErrClosed] if [Watcher.Close] was called. +// +// See [Watcher.AddWith] for a version that allows adding options. +// // # Watching directories // // All files in a directory are monitored, including new files that are created @@ -139,15 +239,63 @@ func (w *Watcher) Close() error { // # Watching files // // Watching individual files (rather than directories) is generally not -// recommended as many tools update files atomically. Instead of "just" writing -// to the file a temporary file will be written to first, and if successful the -// temporary file is moved to to destination removing the original, or some -// variant thereof. The watcher on the original file is now lost, as it no -// longer exists. -// -// Instead, watch the parent directory and use Event.Name to filter out files -// you're not interested in. There is an example of this in [cmd/fsnotify/file.go]. -func (w *Watcher) Add(name string) error { +// recommended as many programs (especially editors) update files atomically: it +// will write to a temporary file which is then moved to to destination, +// overwriting the original (or some variant thereof). The watcher on the +// original file is now lost, as that no longer exists. +// +// The upshot of this is that a power failure or crash won't leave a +// half-written file. +// +// Watch the parent directory and use Event.Name to filter out files you're not +// interested in. There is an example of this in cmd/fsnotify/file.go. +func (w *Watcher) Add(name string) error { return w.AddWith(name) } + +// AddWith is like [Watcher.Add], but allows adding options. When using Add() +// the defaults described below are used. +// +// Possible options are: +// +// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on +// other platforms. The default is 64K (65536 bytes). +func (w *Watcher) AddWith(name string, opts ...addOpt) error { + if w.isClosed() { + return ErrClosed + } + if w.port.PathIsWatched(name) { + return nil + } + + _ = getOptions(opts...) + + // Currently we resolve symlinks that were explicitly requested to be + // watched. Otherwise we would use LStat here. + stat, err := os.Stat(name) + if err != nil { + return err + } + + // Associate all files in the directory. + if stat.IsDir() { + err := w.handleDirectory(name, stat, true, w.associateFile) + if err != nil { + return err + } + + w.mu.Lock() + w.dirs[name] = struct{}{} + w.mu.Unlock() + return nil + } + + err = w.associateFile(name, stat, true) + if err != nil { + return err + } + + w.mu.Lock() + w.watches[name] = struct{}{} + w.mu.Unlock() return nil } @@ -157,6 +305,336 @@ func (w *Watcher) Add(name string) error { // /tmp/dir and /tmp/dir/subdir then you will need to remove both. // // Removing a path that has not yet been added returns [ErrNonExistentWatch]. +// +// Returns nil if [Watcher.Close] was called. func (w *Watcher) Remove(name string) error { + if w.isClosed() { + return nil + } + if !w.port.PathIsWatched(name) { + return fmt.Errorf("%w: %s", ErrNonExistentWatch, name) + } + + // The user has expressed an intent. Immediately remove this name from + // whichever watch list it might be in. If it's not in there the delete + // doesn't cause harm. + w.mu.Lock() + delete(w.watches, name) + delete(w.dirs, name) + w.mu.Unlock() + + stat, err := os.Stat(name) + if err != nil { + return err + } + + // Remove associations for every file in the directory. + if stat.IsDir() { + err := w.handleDirectory(name, stat, false, w.dissociateFile) + if err != nil { + return err + } + return nil + } + + err = w.port.DissociatePath(name) + if err != nil { + return err + } + return nil } + +// readEvents contains the main loop that runs in a goroutine watching for events. +func (w *Watcher) readEvents() { + // If this function returns, the watcher has been closed and we can close + // these channels + defer func() { + close(w.Errors) + close(w.Events) + }() + + pevents := make([]unix.PortEvent, 8) + for { + count, err := w.port.Get(pevents, 1, nil) + if err != nil && err != unix.ETIME { + // Interrupted system call (count should be 0) ignore and continue + if errors.Is(err, unix.EINTR) && count == 0 { + continue + } + // Get failed because we called w.Close() + if errors.Is(err, unix.EBADF) && w.isClosed() { + return + } + // There was an error not caused by calling w.Close() + if !w.sendError(err) { + return + } + } + + p := pevents[:count] + for _, pevent := range p { + if pevent.Source != unix.PORT_SOURCE_FILE { + // Event from unexpected source received; should never happen. + if !w.sendError(errors.New("Event from unexpected source received")) { + return + } + continue + } + + err = w.handleEvent(&pevent) + if err != nil { + if !w.sendError(err) { + return + } + } + } + } +} + +func (w *Watcher) handleDirectory(path string, stat os.FileInfo, follow bool, handler func(string, os.FileInfo, bool) error) error { + files, err := os.ReadDir(path) + if err != nil { + return err + } + + // Handle all children of the directory. + for _, entry := range files { + finfo, err := entry.Info() + if err != nil { + return err + } + err = handler(filepath.Join(path, finfo.Name()), finfo, false) + if err != nil { + return err + } + } + + // And finally handle the directory itself. + return handler(path, stat, follow) +} + +// handleEvent might need to emit more than one fsnotify event if the events +// bitmap matches more than one event type (e.g. the file was both modified and +// had the attributes changed between when the association was created and the +// when event was returned) +func (w *Watcher) handleEvent(event *unix.PortEvent) error { + var ( + events = event.Events + path = event.Path + fmode = event.Cookie.(os.FileMode) + reRegister = true + ) + + w.mu.Lock() + _, watchedDir := w.dirs[path] + _, watchedPath := w.watches[path] + w.mu.Unlock() + isWatched := watchedDir || watchedPath + + if events&unix.FILE_DELETE != 0 { + if !w.sendEvent(path, Remove) { + return nil + } + reRegister = false + } + if events&unix.FILE_RENAME_FROM != 0 { + if !w.sendEvent(path, Rename) { + return nil + } + // Don't keep watching the new file name + reRegister = false + } + if events&unix.FILE_RENAME_TO != 0 { + // We don't report a Rename event for this case, because Rename events + // are interpreted as referring to the _old_ name of the file, and in + // this case the event would refer to the new name of the file. This + // type of rename event is not supported by fsnotify. + + // inotify reports a Remove event in this case, so we simulate this + // here. + if !w.sendEvent(path, Remove) { + return nil + } + // Don't keep watching the file that was removed + reRegister = false + } + + // The file is gone, nothing left to do. + if !reRegister { + if watchedDir { + w.mu.Lock() + delete(w.dirs, path) + w.mu.Unlock() + } + if watchedPath { + w.mu.Lock() + delete(w.watches, path) + w.mu.Unlock() + } + return nil + } + + // If we didn't get a deletion the file still exists and we're going to have + // to watch it again. Let's Stat it now so that we can compare permissions + // and have what we need to continue watching the file + + stat, err := os.Lstat(path) + if err != nil { + // This is unexpected, but we should still emit an event. This happens + // most often on "rm -r" of a subdirectory inside a watched directory We + // get a modify event of something happening inside, but by the time we + // get here, the sudirectory is already gone. Clearly we were watching + // this path but now it is gone. Let's tell the user that it was + // removed. + if !w.sendEvent(path, Remove) { + return nil + } + // Suppress extra write events on removed directories; they are not + // informative and can be confusing. + return nil + } + + // resolve symlinks that were explicitly watched as we would have at Add() + // time. this helps suppress spurious Chmod events on watched symlinks + if isWatched { + stat, err = os.Stat(path) + if err != nil { + // The symlink still exists, but the target is gone. Report the + // Remove similar to above. + if !w.sendEvent(path, Remove) { + return nil + } + // Don't return the error + } + } + + if events&unix.FILE_MODIFIED != 0 { + if fmode.IsDir() { + if watchedDir { + if err := w.updateDirectory(path); err != nil { + return err + } + } else { + if !w.sendEvent(path, Write) { + return nil + } + } + } else { + if !w.sendEvent(path, Write) { + return nil + } + } + } + if events&unix.FILE_ATTRIB != 0 && stat != nil { + // Only send Chmod if perms changed + if stat.Mode().Perm() != fmode.Perm() { + if !w.sendEvent(path, Chmod) { + return nil + } + } + } + + if stat != nil { + // If we get here, it means we've hit an event above that requires us to + // continue watching the file or directory + return w.associateFile(path, stat, isWatched) + } + return nil +} + +func (w *Watcher) updateDirectory(path string) error { + // The directory was modified, so we must find unwatched entities and watch + // them. If something was removed from the directory, nothing will happen, + // as everything else should still be watched. + files, err := os.ReadDir(path) + if err != nil { + return err + } + + for _, entry := range files { + path := filepath.Join(path, entry.Name()) + if w.port.PathIsWatched(path) { + continue + } + + finfo, err := entry.Info() + if err != nil { + return err + } + err = w.associateFile(path, finfo, false) + if err != nil { + if !w.sendError(err) { + return nil + } + } + if !w.sendEvent(path, Create) { + return nil + } + } + return nil +} + +func (w *Watcher) associateFile(path string, stat os.FileInfo, follow bool) error { + if w.isClosed() { + return ErrClosed + } + // This is primarily protecting the call to AssociatePath but it is + // important and intentional that the call to PathIsWatched is also + // protected by this mutex. Without this mutex, AssociatePath has been seen + // to error out that the path is already associated. + w.mu.Lock() + defer w.mu.Unlock() + + if w.port.PathIsWatched(path) { + // Remove the old association in favor of this one If we get ENOENT, + // then while the x/sys/unix wrapper still thought that this path was + // associated, the underlying event port did not. This call will have + // cleared up that discrepancy. The most likely cause is that the event + // has fired but we haven't processed it yet. + err := w.port.DissociatePath(path) + if err != nil && err != unix.ENOENT { + return err + } + } + // FILE_NOFOLLOW means we watch symlinks themselves rather than their + // targets. + events := unix.FILE_MODIFIED | unix.FILE_ATTRIB | unix.FILE_NOFOLLOW + if follow { + // We *DO* follow symlinks for explicitly watched entries. + events = unix.FILE_MODIFIED | unix.FILE_ATTRIB + } + return w.port.AssociatePath(path, stat, + events, + stat.Mode()) +} + +func (w *Watcher) dissociateFile(path string, stat os.FileInfo, unused bool) error { + if !w.port.PathIsWatched(path) { + return nil + } + return w.port.DissociatePath(path) +} + +// WatchList returns all paths explicitly added with [Watcher.Add] (and are not +// yet removed). +// +// Returns nil if [Watcher.Close] was called. +func (w *Watcher) WatchList() []string { + if w.isClosed() { + return nil + } + + w.mu.Lock() + defer w.mu.Unlock() + + entries := make([]string, 0, len(w.watches)+len(w.dirs)) + for pathname := range w.dirs { + entries = append(entries, pathname) + } + for pathname := range w.watches { + entries = append(entries, pathname) + } + + return entries +} diff --git a/vendor/github.com/fsnotify/fsnotify/backend_inotify.go b/vendor/github.com/fsnotify/fsnotify/backend_inotify.go index 54c77fbb0..921c1c1e4 100644 --- a/vendor/github.com/fsnotify/fsnotify/backend_inotify.go +++ b/vendor/github.com/fsnotify/fsnotify/backend_inotify.go @@ -1,5 +1,8 @@ -//go:build linux -// +build linux +//go:build linux && !appengine +// +build linux,!appengine + +// Note: the documentation on the Watcher type and methods is generated from +// mkdoc.zsh package fsnotify @@ -26,9 +29,9 @@ import ( // When a file is removed a Remove event won't be emitted until all file // descriptors are closed, and deletes will always emit a Chmod. For example: // -// fp := os.Open("file") -// os.Remove("file") // Triggers Chmod -// fp.Close() // Triggers Remove +// fp := os.Open("file") +// os.Remove("file") // Triggers Chmod +// fp.Close() // Triggers Remove // // This is the event that inotify sends, so not much can be changed about this. // @@ -42,16 +45,16 @@ import ( // // To increase them you can use sysctl or write the value to the /proc file: // -// # Default values on Linux 5.18 -// sysctl fs.inotify.max_user_watches=124983 -// sysctl fs.inotify.max_user_instances=128 +// # Default values on Linux 5.18 +// sysctl fs.inotify.max_user_watches=124983 +// sysctl fs.inotify.max_user_instances=128 // // To make the changes persist on reboot edit /etc/sysctl.conf or // /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check // your distro's documentation): // -// fs.inotify.max_user_watches=124983 -// fs.inotify.max_user_instances=128 +// fs.inotify.max_user_watches=124983 +// fs.inotify.max_user_instances=128 // // Reaching the limit will result in a "no space left on device" or "too many open // files" error. @@ -67,14 +70,20 @@ import ( // control the maximum number of open files, as well as /etc/login.conf on BSD // systems. // -// # macOS notes +// # Windows notes +// +// Paths can be added as "C:\path\to\dir", but forward slashes +// ("C:/path/to/dir") will also work. // -// Spotlight indexing on macOS can result in multiple events (see [#15]). A -// temporary workaround is to add your folder(s) to the "Spotlight Privacy -// Settings" until we have a native FSEvents implementation (see [#11]). +// When a watched directory is removed it will always send an event for the +// directory itself, but may not send events for all files in that directory. +// Sometimes it will send events for all times, sometimes it will send no +// events, and often only for some files. // -// [#11]: https://github.com/fsnotify/fsnotify/issues/11 -// [#15]: https://github.com/fsnotify/fsnotify/issues/15 +// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest +// value that is guaranteed to work with SMB filesystems. If you have many +// events in quick succession this may not be enough, and you will have to use +// [WithBufferSize] to increase the value. type Watcher struct { // Events sends the filesystem change events. // @@ -101,36 +110,148 @@ type Watcher struct { // initiated by the user may show up as one or multiple // writes, depending on when the system syncs things to // disk. For example when compiling a large Go program - // you may get hundreds of Write events, so you - // probably want to wait until you've stopped receiving - // them (see the dedup example in cmd/fsnotify). + // you may get hundreds of Write events, and you may + // want to wait until you've stopped receiving them + // (see the dedup example in cmd/fsnotify). + // + // Some systems may send Write event for directories + // when the directory content changes. // // fsnotify.Chmod Attributes were changed. On Linux this is also sent // when a file is removed (or more accurately, when a // link to an inode is removed). On kqueue it's sent - // and on kqueue when a file is truncated. On Windows - // it's never sent. + // when a file is truncated. On Windows it's never + // sent. Events chan Event // Errors sends any errors. + // + // ErrEventOverflow is used to indicate there are too many events: + // + // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl) + // - windows: The buffer size is too small; WithBufferSize() can be used to increase it. + // - kqueue, fen: Not used. Errors chan error // Store fd here as os.File.Read() will no longer return on close after // calling Fd(). See: https://github.com/golang/go/issues/26439 fd int - mu sync.Mutex // Map access inotifyFile *os.File - watches map[string]*watch // Map of inotify watches (key: path) - paths map[int]string // Map of watched paths (key: watch descriptor) - done chan struct{} // Channel for sending a "quit message" to the reader goroutine - doneResp chan struct{} // Channel to respond to Close + watches *watches + done chan struct{} // Channel for sending a "quit message" to the reader goroutine + closeMu sync.Mutex + doneResp chan struct{} // Channel to respond to Close +} + +type ( + watches struct { + mu sync.RWMutex + wd map[uint32]*watch // wd → watch + path map[string]uint32 // pathname → wd + } + watch struct { + wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall) + flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags) + path string // Watch path. + } +) + +func newWatches() *watches { + return &watches{ + wd: make(map[uint32]*watch), + path: make(map[string]uint32), + } +} + +func (w *watches) len() int { + w.mu.RLock() + defer w.mu.RUnlock() + return len(w.wd) +} + +func (w *watches) add(ww *watch) { + w.mu.Lock() + defer w.mu.Unlock() + w.wd[ww.wd] = ww + w.path[ww.path] = ww.wd +} + +func (w *watches) remove(wd uint32) { + w.mu.Lock() + defer w.mu.Unlock() + delete(w.path, w.wd[wd].path) + delete(w.wd, wd) +} + +func (w *watches) removePath(path string) (uint32, bool) { + w.mu.Lock() + defer w.mu.Unlock() + + wd, ok := w.path[path] + if !ok { + return 0, false + } + + delete(w.path, path) + delete(w.wd, wd) + + return wd, true +} + +func (w *watches) byPath(path string) *watch { + w.mu.RLock() + defer w.mu.RUnlock() + return w.wd[w.path[path]] +} + +func (w *watches) byWd(wd uint32) *watch { + w.mu.RLock() + defer w.mu.RUnlock() + return w.wd[wd] +} + +func (w *watches) updatePath(path string, f func(*watch) (*watch, error)) error { + w.mu.Lock() + defer w.mu.Unlock() + + var existing *watch + wd, ok := w.path[path] + if ok { + existing = w.wd[wd] + } + + upd, err := f(existing) + if err != nil { + return err + } + if upd != nil { + w.wd[upd.wd] = upd + w.path[upd.path] = upd.wd + + if upd.wd != wd { + delete(w.wd, wd) + } + } + + return nil } // NewWatcher creates a new Watcher. func NewWatcher() (*Watcher, error) { - // Create inotify fd - // Need to set the FD to nonblocking mode in order for SetDeadline methods to work - // Otherwise, blocking i/o operations won't terminate on close + return NewBufferedWatcher(0) +} + +// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events +// channel. +// +// The main use case for this is situations with a very large number of events +// where the kernel buffer size can't be increased (e.g. due to lack of +// permissions). An unbuffered Watcher will perform better for almost all use +// cases, and whenever possible you will be better off increasing the kernel +// buffers instead of adding a large userspace buffer. +func NewBufferedWatcher(sz uint) (*Watcher, error) { + // Need to set nonblocking mode for SetDeadline to work, otherwise blocking + // I/O operations won't terminate on close. fd, errno := unix.InotifyInit1(unix.IN_CLOEXEC | unix.IN_NONBLOCK) if fd == -1 { return nil, errno @@ -139,9 +260,8 @@ func NewWatcher() (*Watcher, error) { w := &Watcher{ fd: fd, inotifyFile: os.NewFile(uintptr(fd), ""), - watches: make(map[string]*watch), - paths: make(map[int]string), - Events: make(chan Event), + watches: newWatches(), + Events: make(chan Event, sz), Errors: make(chan error), done: make(chan struct{}), doneResp: make(chan struct{}), @@ -157,8 +277,8 @@ func (w *Watcher) sendEvent(e Event) bool { case w.Events <- e: return true case <-w.done: + return false } - return false } // Returns true if the error was sent, or false if watcher is closed. @@ -180,17 +300,15 @@ func (w *Watcher) isClosed() bool { } } -// Close removes all watches and closes the events channel. +// Close removes all watches and closes the Events channel. func (w *Watcher) Close() error { - w.mu.Lock() + w.closeMu.Lock() if w.isClosed() { - w.mu.Unlock() + w.closeMu.Unlock() return nil } - - // Send 'close' signal to goroutine, and set the Watcher to closed. close(w.done) - w.mu.Unlock() + w.closeMu.Unlock() // Causes any blocking reads to return with an error, provided the file // still supports deadline operations. @@ -207,17 +325,21 @@ func (w *Watcher) Close() error { // Add starts monitoring the path for changes. // -// A path can only be watched once; attempting to watch it more than once will -// return an error. Paths that do not yet exist on the filesystem cannot be -// added. A watch will be automatically removed if the path is deleted. +// A path can only be watched once; watching it more than once is a no-op and will +// not return an error. Paths that do not yet exist on the filesystem cannot be +// watched. // -// A path will remain watched if it gets renamed to somewhere else on the same -// filesystem, but the monitor will get removed if the path gets deleted and -// re-created, or if it's moved to a different filesystem. +// A watch will be automatically removed if the watched path is deleted or +// renamed. The exception is the Windows backend, which doesn't remove the +// watcher on renames. // // Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special // filesystems (/proc, /sys, etc.) generally don't work. // +// Returns [ErrClosed] if [Watcher.Close] was called. +// +// See [Watcher.AddWith] for a version that allows adding options. +// // # Watching directories // // All files in a directory are monitored, including new files that are created @@ -227,44 +349,59 @@ func (w *Watcher) Close() error { // # Watching files // // Watching individual files (rather than directories) is generally not -// recommended as many tools update files atomically. Instead of "just" writing -// to the file a temporary file will be written to first, and if successful the -// temporary file is moved to to destination removing the original, or some -// variant thereof. The watcher on the original file is now lost, as it no -// longer exists. -// -// Instead, watch the parent directory and use Event.Name to filter out files -// you're not interested in. There is an example of this in [cmd/fsnotify/file.go]. -func (w *Watcher) Add(name string) error { - name = filepath.Clean(name) +// recommended as many programs (especially editors) update files atomically: it +// will write to a temporary file which is then moved to to destination, +// overwriting the original (or some variant thereof). The watcher on the +// original file is now lost, as that no longer exists. +// +// The upshot of this is that a power failure or crash won't leave a +// half-written file. +// +// Watch the parent directory and use Event.Name to filter out files you're not +// interested in. There is an example of this in cmd/fsnotify/file.go. +func (w *Watcher) Add(name string) error { return w.AddWith(name) } + +// AddWith is like [Watcher.Add], but allows adding options. When using Add() +// the defaults described below are used. +// +// Possible options are: +// +// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on +// other platforms. The default is 64K (65536 bytes). +func (w *Watcher) AddWith(name string, opts ...addOpt) error { if w.isClosed() { - return errors.New("inotify instance already closed") + return ErrClosed } + name = filepath.Clean(name) + _ = getOptions(opts...) + var flags uint32 = unix.IN_MOVED_TO | unix.IN_MOVED_FROM | unix.IN_CREATE | unix.IN_ATTRIB | unix.IN_MODIFY | unix.IN_MOVE_SELF | unix.IN_DELETE | unix.IN_DELETE_SELF - w.mu.Lock() - defer w.mu.Unlock() - watchEntry := w.watches[name] - if watchEntry != nil { - flags |= watchEntry.flags | unix.IN_MASK_ADD - } - wd, errno := unix.InotifyAddWatch(w.fd, name, flags) - if wd == -1 { - return errno - } + return w.watches.updatePath(name, func(existing *watch) (*watch, error) { + if existing != nil { + flags |= existing.flags | unix.IN_MASK_ADD + } - if watchEntry == nil { - w.watches[name] = &watch{wd: uint32(wd), flags: flags} - w.paths[wd] = name - } else { - watchEntry.wd = uint32(wd) - watchEntry.flags = flags - } + wd, err := unix.InotifyAddWatch(w.fd, name, flags) + if wd == -1 { + return nil, err + } - return nil + if existing == nil { + return &watch{ + wd: uint32(wd), + path: name, + flags: flags, + }, nil + } + + existing.wd = uint32(wd) + existing.flags = flags + return existing, nil + }) } // Remove stops monitoring the path for changes. @@ -273,32 +410,22 @@ func (w *Watcher) Add(name string) error { // /tmp/dir and /tmp/dir/subdir then you will need to remove both. // // Removing a path that has not yet been added returns [ErrNonExistentWatch]. +// +// Returns nil if [Watcher.Close] was called. func (w *Watcher) Remove(name string) error { - name = filepath.Clean(name) - - // Fetch the watch. - w.mu.Lock() - defer w.mu.Unlock() - watch, ok := w.watches[name] + if w.isClosed() { + return nil + } + return w.remove(filepath.Clean(name)) +} - // Remove it from inotify. +func (w *Watcher) remove(name string) error { + wd, ok := w.watches.removePath(name) if !ok { return fmt.Errorf("%w: %s", ErrNonExistentWatch, name) } - // We successfully removed the watch if InotifyRmWatch doesn't return an - // error, we need to clean up our internal state to ensure it matches - // inotify's kernel state. - delete(w.paths, int(watch.wd)) - delete(w.watches, name) - - // inotify_rm_watch will return EINVAL if the file has been deleted; - // the inotify will already have been removed. - // watches and pathes are deleted in ignoreLinux() implicitly and asynchronously - // by calling inotify_rm_watch() below. e.g. readEvents() goroutine receives IN_IGNORE - // so that EINVAL means that the wd is being rm_watch()ed or its file removed - // by another thread and we have not received IN_IGNORE event. - success, errno := unix.InotifyRmWatch(w.fd, watch.wd) + success, errno := unix.InotifyRmWatch(w.fd, wd) if success == -1 { // TODO: Perhaps it's not helpful to return an error here in every case; // The only two possible errors are: @@ -312,28 +439,28 @@ func (w *Watcher) Remove(name string) error { // are watching is deleted. return errno } - return nil } -// WatchList returns all paths added with [Add] (and are not yet removed). +// WatchList returns all paths explicitly added with [Watcher.Add] (and are not +// yet removed). +// +// Returns nil if [Watcher.Close] was called. func (w *Watcher) WatchList() []string { - w.mu.Lock() - defer w.mu.Unlock() + if w.isClosed() { + return nil + } - entries := make([]string, 0, len(w.watches)) - for pathname := range w.watches { + entries := make([]string, 0, w.watches.len()) + w.watches.mu.RLock() + for pathname := range w.watches.path { entries = append(entries, pathname) } + w.watches.mu.RUnlock() return entries } -type watch struct { - wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall) - flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags) -} - // readEvents reads from the inotify file descriptor, converts the // received events into Event objects and sends them via the Events channel func (w *Watcher) readEvents() { @@ -367,14 +494,11 @@ func (w *Watcher) readEvents() { if n < unix.SizeofInotifyEvent { var err error if n == 0 { - // If EOF is received. This should really never happen. - err = io.EOF + err = io.EOF // If EOF is received. This should really never happen. } else if n < 0 { - // If an error occurred while reading. - err = errno + err = errno // If an error occurred while reading. } else { - // Read was too short. - err = errors.New("notify: short read in readEvents()") + err = errors.New("notify: short read in readEvents()") // Read was too short. } if !w.sendError(err) { return @@ -403,18 +527,29 @@ func (w *Watcher) readEvents() { // doesn't append the filename to the event, but we would like to always fill the // the "Name" field with a valid filename. We retrieve the path of the watch from // the "paths" map. - w.mu.Lock() - name, ok := w.paths[int(raw.Wd)] - // IN_DELETE_SELF occurs when the file/directory being watched is removed. - // This is a sign to clean up the maps, otherwise we are no longer in sync - // with the inotify kernel state which has already deleted the watch - // automatically. - if ok && mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF { - delete(w.paths, int(raw.Wd)) - delete(w.watches, name) + watch := w.watches.byWd(uint32(raw.Wd)) + + // inotify will automatically remove the watch on deletes; just need + // to clean our state here. + if watch != nil && mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF { + w.watches.remove(watch.wd) + } + // We can't really update the state when a watched path is moved; + // only IN_MOVE_SELF is sent and not IN_MOVED_{FROM,TO}. So remove + // the watch. + if watch != nil && mask&unix.IN_MOVE_SELF == unix.IN_MOVE_SELF { + err := w.remove(watch.path) + if err != nil && !errors.Is(err, ErrNonExistentWatch) { + if !w.sendError(err) { + return + } + } } - w.mu.Unlock() + var name string + if watch != nil { + name = watch.path + } if nameLen > 0 { // Point "bytes" at the first byte of the filename bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent]))[:nameLen:nameLen] diff --git a/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go b/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go index 29087469b..063a0915a 100644 --- a/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go +++ b/vendor/github.com/fsnotify/fsnotify/backend_kqueue.go @@ -1,12 +1,14 @@ //go:build freebsd || openbsd || netbsd || dragonfly || darwin // +build freebsd openbsd netbsd dragonfly darwin +// Note: the documentation on the Watcher type and methods is generated from +// mkdoc.zsh + package fsnotify import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" "sync" @@ -24,9 +26,9 @@ import ( // When a file is removed a Remove event won't be emitted until all file // descriptors are closed, and deletes will always emit a Chmod. For example: // -// fp := os.Open("file") -// os.Remove("file") // Triggers Chmod -// fp.Close() // Triggers Remove +// fp := os.Open("file") +// os.Remove("file") // Triggers Chmod +// fp.Close() // Triggers Remove // // This is the event that inotify sends, so not much can be changed about this. // @@ -40,16 +42,16 @@ import ( // // To increase them you can use sysctl or write the value to the /proc file: // -// # Default values on Linux 5.18 -// sysctl fs.inotify.max_user_watches=124983 -// sysctl fs.inotify.max_user_instances=128 +// # Default values on Linux 5.18 +// sysctl fs.inotify.max_user_watches=124983 +// sysctl fs.inotify.max_user_instances=128 // // To make the changes persist on reboot edit /etc/sysctl.conf or // /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check // your distro's documentation): // -// fs.inotify.max_user_watches=124983 -// fs.inotify.max_user_instances=128 +// fs.inotify.max_user_watches=124983 +// fs.inotify.max_user_instances=128 // // Reaching the limit will result in a "no space left on device" or "too many open // files" error. @@ -65,14 +67,20 @@ import ( // control the maximum number of open files, as well as /etc/login.conf on BSD // systems. // -// # macOS notes +// # Windows notes +// +// Paths can be added as "C:\path\to\dir", but forward slashes +// ("C:/path/to/dir") will also work. // -// Spotlight indexing on macOS can result in multiple events (see [#15]). A -// temporary workaround is to add your folder(s) to the "Spotlight Privacy -// Settings" until we have a native FSEvents implementation (see [#11]). +// When a watched directory is removed it will always send an event for the +// directory itself, but may not send events for all files in that directory. +// Sometimes it will send events for all times, sometimes it will send no +// events, and often only for some files. // -// [#11]: https://github.com/fsnotify/fsnotify/issues/11 -// [#15]: https://github.com/fsnotify/fsnotify/issues/15 +// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest +// value that is guaranteed to work with SMB filesystems. If you have many +// events in quick succession this may not be enough, and you will have to use +// [WithBufferSize] to increase the value. type Watcher struct { // Events sends the filesystem change events. // @@ -99,18 +107,27 @@ type Watcher struct { // initiated by the user may show up as one or multiple // writes, depending on when the system syncs things to // disk. For example when compiling a large Go program - // you may get hundreds of Write events, so you - // probably want to wait until you've stopped receiving - // them (see the dedup example in cmd/fsnotify). + // you may get hundreds of Write events, and you may + // want to wait until you've stopped receiving them + // (see the dedup example in cmd/fsnotify). + // + // Some systems may send Write event for directories + // when the directory content changes. // // fsnotify.Chmod Attributes were changed. On Linux this is also sent // when a file is removed (or more accurately, when a // link to an inode is removed). On kqueue it's sent - // and on kqueue when a file is truncated. On Windows - // it's never sent. + // when a file is truncated. On Windows it's never + // sent. Events chan Event // Errors sends any errors. + // + // ErrEventOverflow is used to indicate there are too many events: + // + // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl) + // - windows: The buffer size is too small; WithBufferSize() can be used to increase it. + // - kqueue, fen: Not used. Errors chan error done chan struct{} @@ -133,6 +150,18 @@ type pathInfo struct { // NewWatcher creates a new Watcher. func NewWatcher() (*Watcher, error) { + return NewBufferedWatcher(0) +} + +// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events +// channel. +// +// The main use case for this is situations with a very large number of events +// where the kernel buffer size can't be increased (e.g. due to lack of +// permissions). An unbuffered Watcher will perform better for almost all use +// cases, and whenever possible you will be better off increasing the kernel +// buffers instead of adding a large userspace buffer. +func NewBufferedWatcher(sz uint) (*Watcher, error) { kq, closepipe, err := newKqueue() if err != nil { return nil, err @@ -147,7 +176,7 @@ func NewWatcher() (*Watcher, error) { paths: make(map[int]pathInfo), fileExists: make(map[string]struct{}), userWatches: make(map[string]struct{}), - Events: make(chan Event), + Events: make(chan Event, sz), Errors: make(chan error), done: make(chan struct{}), } @@ -197,8 +226,8 @@ func (w *Watcher) sendEvent(e Event) bool { case w.Events <- e: return true case <-w.done: + return false } - return false } // Returns true if the error was sent, or false if watcher is closed. @@ -207,11 +236,11 @@ func (w *Watcher) sendError(err error) bool { case w.Errors <- err: return true case <-w.done: + return false } - return false } -// Close removes all watches and closes the events channel. +// Close removes all watches and closes the Events channel. func (w *Watcher) Close() error { w.mu.Lock() if w.isClosed { @@ -239,17 +268,21 @@ func (w *Watcher) Close() error { // Add starts monitoring the path for changes. // -// A path can only be watched once; attempting to watch it more than once will -// return an error. Paths that do not yet exist on the filesystem cannot be -// added. A watch will be automatically removed if the path is deleted. +// A path can only be watched once; watching it more than once is a no-op and will +// not return an error. Paths that do not yet exist on the filesystem cannot be +// watched. // -// A path will remain watched if it gets renamed to somewhere else on the same -// filesystem, but the monitor will get removed if the path gets deleted and -// re-created, or if it's moved to a different filesystem. +// A watch will be automatically removed if the watched path is deleted or +// renamed. The exception is the Windows backend, which doesn't remove the +// watcher on renames. // // Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special // filesystems (/proc, /sys, etc.) generally don't work. // +// Returns [ErrClosed] if [Watcher.Close] was called. +// +// See [Watcher.AddWith] for a version that allows adding options. +// // # Watching directories // // All files in a directory are monitored, including new files that are created @@ -259,15 +292,28 @@ func (w *Watcher) Close() error { // # Watching files // // Watching individual files (rather than directories) is generally not -// recommended as many tools update files atomically. Instead of "just" writing -// to the file a temporary file will be written to first, and if successful the -// temporary file is moved to to destination removing the original, or some -// variant thereof. The watcher on the original file is now lost, as it no -// longer exists. -// -// Instead, watch the parent directory and use Event.Name to filter out files -// you're not interested in. There is an example of this in [cmd/fsnotify/file.go]. -func (w *Watcher) Add(name string) error { +// recommended as many programs (especially editors) update files atomically: it +// will write to a temporary file which is then moved to to destination, +// overwriting the original (or some variant thereof). The watcher on the +// original file is now lost, as that no longer exists. +// +// The upshot of this is that a power failure or crash won't leave a +// half-written file. +// +// Watch the parent directory and use Event.Name to filter out files you're not +// interested in. There is an example of this in cmd/fsnotify/file.go. +func (w *Watcher) Add(name string) error { return w.AddWith(name) } + +// AddWith is like [Watcher.Add], but allows adding options. When using Add() +// the defaults described below are used. +// +// Possible options are: +// +// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on +// other platforms. The default is 64K (65536 bytes). +func (w *Watcher) AddWith(name string, opts ...addOpt) error { + _ = getOptions(opts...) + w.mu.Lock() w.userWatches[name] = struct{}{} w.mu.Unlock() @@ -281,9 +327,19 @@ func (w *Watcher) Add(name string) error { // /tmp/dir and /tmp/dir/subdir then you will need to remove both. // // Removing a path that has not yet been added returns [ErrNonExistentWatch]. +// +// Returns nil if [Watcher.Close] was called. func (w *Watcher) Remove(name string) error { + return w.remove(name, true) +} + +func (w *Watcher) remove(name string, unwatchFiles bool) error { name = filepath.Clean(name) w.mu.Lock() + if w.isClosed { + w.mu.Unlock() + return nil + } watchfd, ok := w.watches[name] w.mu.Unlock() if !ok { @@ -315,7 +371,7 @@ func (w *Watcher) Remove(name string) error { w.mu.Unlock() // Find all watched paths that are in this directory that are not external. - if isDir { + if unwatchFiles && isDir { var pathsToRemove []string w.mu.Lock() for fd := range w.watchesByDir[name] { @@ -326,20 +382,25 @@ func (w *Watcher) Remove(name string) error { } w.mu.Unlock() for _, name := range pathsToRemove { - // Since these are internal, not much sense in propagating error - // to the user, as that will just confuse them with an error about - // a path they did not explicitly watch themselves. + // Since these are internal, not much sense in propagating error to + // the user, as that will just confuse them with an error about a + // path they did not explicitly watch themselves. w.Remove(name) } } - return nil } -// WatchList returns all paths added with [Add] (and are not yet removed). +// WatchList returns all paths explicitly added with [Watcher.Add] (and are not +// yet removed). +// +// Returns nil if [Watcher.Close] was called. func (w *Watcher) WatchList() []string { w.mu.Lock() defer w.mu.Unlock() + if w.isClosed { + return nil + } entries := make([]string, 0, len(w.userWatches)) for pathname := range w.userWatches { @@ -352,18 +413,18 @@ func (w *Watcher) WatchList() []string { // Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE) const noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | unix.NOTE_RENAME -// addWatch adds name to the watched file set. -// The flags are interpreted as described in kevent(2). -// Returns the real path to the file which was added, if any, which may be different from the one passed in the case of symlinks. +// addWatch adds name to the watched file set; the flags are interpreted as +// described in kevent(2). +// +// Returns the real path to the file which was added, with symlinks resolved. func (w *Watcher) addWatch(name string, flags uint32) (string, error) { var isDir bool - // Make ./name and name equivalent name = filepath.Clean(name) w.mu.Lock() if w.isClosed { w.mu.Unlock() - return "", errors.New("kevent instance already closed") + return "", ErrClosed } watchfd, alreadyWatching := w.watches[name] // We already have a watch, but we can still override flags. @@ -383,27 +444,30 @@ func (w *Watcher) addWatch(name string, flags uint32) (string, error) { return "", nil } - // Follow Symlinks - // - // Linux can add unresolvable symlinks to the watch list without issue, - // and Windows can't do symlinks period. To maintain consistency, we - // will act like everything is fine if the link can't be resolved. - // There will simply be no file events for broken symlinks. Hence the - // returns of nil on errors. + // Follow Symlinks. if fi.Mode()&os.ModeSymlink == os.ModeSymlink { - name, err = filepath.EvalSymlinks(name) + link, err := os.Readlink(name) if err != nil { + // Return nil because Linux can add unresolvable symlinks to the + // watch list without problems, so maintain consistency with + // that. There will be no file events for broken symlinks. + // TODO: more specific check; returns os.PathError; ENOENT? return "", nil } w.mu.Lock() - _, alreadyWatching = w.watches[name] + _, alreadyWatching = w.watches[link] w.mu.Unlock() if alreadyWatching { - return name, nil + // Add to watches so we don't get spurious Create events later + // on when we diff the directories. + w.watches[name] = 0 + w.fileExists[name] = struct{}{} + return link, nil } + name = link fi, err = os.Lstat(name) if err != nil { return "", nil @@ -411,7 +475,7 @@ func (w *Watcher) addWatch(name string, flags uint32) (string, error) { } // Retry on EINTR; open() can return EINTR in practice on macOS. - // See #354, and go issues 11180 and 39237. + // See #354, and Go issues 11180 and 39237. for { watchfd, err = unix.Open(name, openMode, 0) if err == nil { @@ -444,14 +508,13 @@ func (w *Watcher) addWatch(name string, flags uint32) (string, error) { w.watchesByDir[parentName] = watchesByDir } watchesByDir[watchfd] = struct{}{} - w.paths[watchfd] = pathInfo{name: name, isDir: isDir} w.mu.Unlock() } if isDir { - // Watch the directory if it has not been watched before, - // or if it was watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles) + // Watch the directory if it has not been watched before, or if it was + // watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles) w.mu.Lock() watchDir := (flags&unix.NOTE_WRITE) == unix.NOTE_WRITE && @@ -473,13 +536,10 @@ func (w *Watcher) addWatch(name string, flags uint32) (string, error) { // Event values that it sends down the Events channel. func (w *Watcher) readEvents() { defer func() { - err := unix.Close(w.kq) - if err != nil { - w.Errors <- err - } - unix.Close(w.closepipe[0]) close(w.Events) close(w.Errors) + _ = unix.Close(w.kq) + unix.Close(w.closepipe[0]) }() eventBuffer := make([]unix.Kevent_t, 10) @@ -513,18 +573,8 @@ func (w *Watcher) readEvents() { event := w.newEvent(path.name, mask) - if path.isDir && !event.Has(Remove) { - // Double check to make sure the directory exists. This can - // happen when we do a rm -fr on a recursively watched folders - // and we receive a modification event first but the folder has - // been deleted and later receive the delete event. - if _, err := os.Lstat(event.Name); os.IsNotExist(err) { - event.Op |= Remove - } - } - if event.Has(Rename) || event.Has(Remove) { - w.Remove(event.Name) + w.remove(event.Name, false) w.mu.Lock() delete(w.fileExists, event.Name) w.mu.Unlock() @@ -540,26 +590,30 @@ func (w *Watcher) readEvents() { } if event.Has(Remove) { - // Look for a file that may have overwritten this. - // For example, mv f1 f2 will delete f2, then create f2. + // Look for a file that may have overwritten this; for example, + // mv f1 f2 will delete f2, then create f2. if path.isDir { fileDir := filepath.Clean(event.Name) w.mu.Lock() _, found := w.watches[fileDir] w.mu.Unlock() if found { - // make sure the directory exists before we watch for changes. When we - // do a recursive watch and perform rm -fr, the parent directory might - // have gone missing, ignore the missing directory and let the - // upcoming delete event remove the watch from the parent directory. - if _, err := os.Lstat(fileDir); err == nil { - w.sendDirectoryChangeEvents(fileDir) + err := w.sendDirectoryChangeEvents(fileDir) + if err != nil { + if !w.sendError(err) { + closed = true + } } } } else { filePath := filepath.Clean(event.Name) - if fileInfo, err := os.Lstat(filePath); err == nil { - w.sendFileCreatedEventIfNew(filePath, fileInfo) + if fi, err := os.Lstat(filePath); err == nil { + err := w.sendFileCreatedEventIfNew(filePath, fi) + if err != nil { + if !w.sendError(err) { + closed = true + } + } } } } @@ -582,21 +636,31 @@ func (w *Watcher) newEvent(name string, mask uint32) Event { if mask&unix.NOTE_ATTRIB == unix.NOTE_ATTRIB { e.Op |= Chmod } + // No point sending a write and delete event at the same time: if it's gone, + // then it's gone. + if e.Op.Has(Write) && e.Op.Has(Remove) { + e.Op &^= Write + } return e } // watchDirectoryFiles to mimic inotify when adding a watch on a directory func (w *Watcher) watchDirectoryFiles(dirPath string) error { // Get all files - files, err := ioutil.ReadDir(dirPath) + files, err := os.ReadDir(dirPath) if err != nil { return err } - for _, fileInfo := range files { - path := filepath.Join(dirPath, fileInfo.Name()) + for _, f := range files { + path := filepath.Join(dirPath, f.Name()) + + fi, err := f.Info() + if err != nil { + return fmt.Errorf("%q: %w", path, err) + } - cleanPath, err := w.internalWatch(path, fileInfo) + cleanPath, err := w.internalWatch(path, fi) if err != nil { // No permission to read the file; that's not a problem: just skip. // But do add it to w.fileExists to prevent it from being picked up @@ -606,7 +670,7 @@ func (w *Watcher) watchDirectoryFiles(dirPath string) error { case errors.Is(err, unix.EACCES) || errors.Is(err, unix.EPERM): cleanPath = filepath.Clean(path) default: - return fmt.Errorf("%q: %w", filepath.Join(dirPath, fileInfo.Name()), err) + return fmt.Errorf("%q: %w", path, err) } } @@ -622,26 +686,37 @@ func (w *Watcher) watchDirectoryFiles(dirPath string) error { // // This functionality is to have the BSD watcher match the inotify, which sends // a create event for files created in a watched directory. -func (w *Watcher) sendDirectoryChangeEvents(dir string) { - // Get all files - files, err := ioutil.ReadDir(dir) +func (w *Watcher) sendDirectoryChangeEvents(dir string) error { + files, err := os.ReadDir(dir) if err != nil { - if !w.sendError(fmt.Errorf("fsnotify.sendDirectoryChangeEvents: %w", err)) { - return + // Directory no longer exists: we can ignore this safely. kqueue will + // still give us the correct events. + if errors.Is(err, os.ErrNotExist) { + return nil } + return fmt.Errorf("fsnotify.sendDirectoryChangeEvents: %w", err) } - // Search for new files - for _, fi := range files { - err := w.sendFileCreatedEventIfNew(filepath.Join(dir, fi.Name()), fi) + for _, f := range files { + fi, err := f.Info() if err != nil { - return + return fmt.Errorf("fsnotify.sendDirectoryChangeEvents: %w", err) + } + + err = w.sendFileCreatedEventIfNew(filepath.Join(dir, fi.Name()), fi) + if err != nil { + // Don't need to send an error if this file isn't readable. + if errors.Is(err, unix.EACCES) || errors.Is(err, unix.EPERM) { + return nil + } + return fmt.Errorf("fsnotify.sendDirectoryChangeEvents: %w", err) } } + return nil } // sendFileCreatedEvent sends a create event if the file isn't already being tracked. -func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fileInfo os.FileInfo) (err error) { +func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fi os.FileInfo) (err error) { w.mu.Lock() _, doesExist := w.fileExists[filePath] w.mu.Unlock() @@ -652,7 +727,7 @@ func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fileInfo os.FileInf } // like watchDirectoryFiles (but without doing another ReadDir) - filePath, err = w.internalWatch(filePath, fileInfo) + filePath, err = w.internalWatch(filePath, fi) if err != nil { return err } @@ -664,10 +739,10 @@ func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fileInfo os.FileInf return nil } -func (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) (string, error) { - if fileInfo.IsDir() { - // mimic Linux providing delete events for subdirectories - // but preserve the flags used if currently watching subdirectory +func (w *Watcher) internalWatch(name string, fi os.FileInfo) (string, error) { + if fi.IsDir() { + // mimic Linux providing delete events for subdirectories, but preserve + // the flags used if currently watching subdirectory w.mu.Lock() flags := w.dirFlags[name] w.mu.Unlock() diff --git a/vendor/github.com/fsnotify/fsnotify/backend_other.go b/vendor/github.com/fsnotify/fsnotify/backend_other.go index a9bb1c3c4..d34a23c01 100644 --- a/vendor/github.com/fsnotify/fsnotify/backend_other.go +++ b/vendor/github.com/fsnotify/fsnotify/backend_other.go @@ -1,39 +1,169 @@ -//go:build !darwin && !dragonfly && !freebsd && !openbsd && !linux && !netbsd && !solaris && !windows -// +build !darwin,!dragonfly,!freebsd,!openbsd,!linux,!netbsd,!solaris,!windows +//go:build appengine || (!darwin && !dragonfly && !freebsd && !openbsd && !linux && !netbsd && !solaris && !windows) +// +build appengine !darwin,!dragonfly,!freebsd,!openbsd,!linux,!netbsd,!solaris,!windows + +// Note: the documentation on the Watcher type and methods is generated from +// mkdoc.zsh package fsnotify -import ( - "fmt" - "runtime" -) +import "errors" -// Watcher watches a set of files, delivering events to a channel. -type Watcher struct{} +// Watcher watches a set of paths, delivering events on a channel. +// +// A watcher should not be copied (e.g. pass it by pointer, rather than by +// value). +// +// # Linux notes +// +// When a file is removed a Remove event won't be emitted until all file +// descriptors are closed, and deletes will always emit a Chmod. For example: +// +// fp := os.Open("file") +// os.Remove("file") // Triggers Chmod +// fp.Close() // Triggers Remove +// +// This is the event that inotify sends, so not much can be changed about this. +// +// The fs.inotify.max_user_watches sysctl variable specifies the upper limit +// for the number of watches per user, and fs.inotify.max_user_instances +// specifies the maximum number of inotify instances per user. Every Watcher you +// create is an "instance", and every path you add is a "watch". +// +// These are also exposed in /proc as /proc/sys/fs/inotify/max_user_watches and +// /proc/sys/fs/inotify/max_user_instances +// +// To increase them you can use sysctl or write the value to the /proc file: +// +// # Default values on Linux 5.18 +// sysctl fs.inotify.max_user_watches=124983 +// sysctl fs.inotify.max_user_instances=128 +// +// To make the changes persist on reboot edit /etc/sysctl.conf or +// /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check +// your distro's documentation): +// +// fs.inotify.max_user_watches=124983 +// fs.inotify.max_user_instances=128 +// +// Reaching the limit will result in a "no space left on device" or "too many open +// files" error. +// +// # kqueue notes (macOS, BSD) +// +// kqueue requires opening a file descriptor for every file that's being watched; +// so if you're watching a directory with five files then that's six file +// descriptors. You will run in to your system's "max open files" limit faster on +// these platforms. +// +// The sysctl variables kern.maxfiles and kern.maxfilesperproc can be used to +// control the maximum number of open files, as well as /etc/login.conf on BSD +// systems. +// +// # Windows notes +// +// Paths can be added as "C:\path\to\dir", but forward slashes +// ("C:/path/to/dir") will also work. +// +// When a watched directory is removed it will always send an event for the +// directory itself, but may not send events for all files in that directory. +// Sometimes it will send events for all times, sometimes it will send no +// events, and often only for some files. +// +// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest +// value that is guaranteed to work with SMB filesystems. If you have many +// events in quick succession this may not be enough, and you will have to use +// [WithBufferSize] to increase the value. +type Watcher struct { + // Events sends the filesystem change events. + // + // fsnotify can send the following events; a "path" here can refer to a + // file, directory, symbolic link, or special file like a FIFO. + // + // fsnotify.Create A new path was created; this may be followed by one + // or more Write events if data also gets written to a + // file. + // + // fsnotify.Remove A path was removed. + // + // fsnotify.Rename A path was renamed. A rename is always sent with the + // old path as Event.Name, and a Create event will be + // sent with the new name. Renames are only sent for + // paths that are currently watched; e.g. moving an + // unmonitored file into a monitored directory will + // show up as just a Create. Similarly, renaming a file + // to outside a monitored directory will show up as + // only a Rename. + // + // fsnotify.Write A file or named pipe was written to. A Truncate will + // also trigger a Write. A single "write action" + // initiated by the user may show up as one or multiple + // writes, depending on when the system syncs things to + // disk. For example when compiling a large Go program + // you may get hundreds of Write events, and you may + // want to wait until you've stopped receiving them + // (see the dedup example in cmd/fsnotify). + // + // Some systems may send Write event for directories + // when the directory content changes. + // + // fsnotify.Chmod Attributes were changed. On Linux this is also sent + // when a file is removed (or more accurately, when a + // link to an inode is removed). On kqueue it's sent + // when a file is truncated. On Windows it's never + // sent. + Events chan Event + + // Errors sends any errors. + // + // ErrEventOverflow is used to indicate there are too many events: + // + // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl) + // - windows: The buffer size is too small; WithBufferSize() can be used to increase it. + // - kqueue, fen: Not used. + Errors chan error +} // NewWatcher creates a new Watcher. func NewWatcher() (*Watcher, error) { - return nil, fmt.Errorf("fsnotify not supported on %s", runtime.GOOS) + return nil, errors.New("fsnotify not supported on the current platform") } -// Close removes all watches and closes the events channel. -func (w *Watcher) Close() error { - return nil -} +// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events +// channel. +// +// The main use case for this is situations with a very large number of events +// where the kernel buffer size can't be increased (e.g. due to lack of +// permissions). An unbuffered Watcher will perform better for almost all use +// cases, and whenever possible you will be better off increasing the kernel +// buffers instead of adding a large userspace buffer. +func NewBufferedWatcher(sz uint) (*Watcher, error) { return NewWatcher() } + +// Close removes all watches and closes the Events channel. +func (w *Watcher) Close() error { return nil } + +// WatchList returns all paths explicitly added with [Watcher.Add] (and are not +// yet removed). +// +// Returns nil if [Watcher.Close] was called. +func (w *Watcher) WatchList() []string { return nil } // Add starts monitoring the path for changes. // -// A path can only be watched once; attempting to watch it more than once will -// return an error. Paths that do not yet exist on the filesystem cannot be -// added. A watch will be automatically removed if the path is deleted. +// A path can only be watched once; watching it more than once is a no-op and will +// not return an error. Paths that do not yet exist on the filesystem cannot be +// watched. // -// A path will remain watched if it gets renamed to somewhere else on the same -// filesystem, but the monitor will get removed if the path gets deleted and -// re-created, or if it's moved to a different filesystem. +// A watch will be automatically removed if the watched path is deleted or +// renamed. The exception is the Windows backend, which doesn't remove the +// watcher on renames. // // Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special // filesystems (/proc, /sys, etc.) generally don't work. // +// Returns [ErrClosed] if [Watcher.Close] was called. +// +// See [Watcher.AddWith] for a version that allows adding options. +// // # Watching directories // // All files in a directory are monitored, including new files that are created @@ -43,17 +173,26 @@ func (w *Watcher) Close() error { // # Watching files // // Watching individual files (rather than directories) is generally not -// recommended as many tools update files atomically. Instead of "just" writing -// to the file a temporary file will be written to first, and if successful the -// temporary file is moved to to destination removing the original, or some -// variant thereof. The watcher on the original file is now lost, as it no -// longer exists. -// -// Instead, watch the parent directory and use Event.Name to filter out files -// you're not interested in. There is an example of this in [cmd/fsnotify/file.go]. -func (w *Watcher) Add(name string) error { - return nil -} +// recommended as many programs (especially editors) update files atomically: it +// will write to a temporary file which is then moved to to destination, +// overwriting the original (or some variant thereof). The watcher on the +// original file is now lost, as that no longer exists. +// +// The upshot of this is that a power failure or crash won't leave a +// half-written file. +// +// Watch the parent directory and use Event.Name to filter out files you're not +// interested in. There is an example of this in cmd/fsnotify/file.go. +func (w *Watcher) Add(name string) error { return nil } + +// AddWith is like [Watcher.Add], but allows adding options. When using Add() +// the defaults described below are used. +// +// Possible options are: +// +// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on +// other platforms. The default is 64K (65536 bytes). +func (w *Watcher) AddWith(name string, opts ...addOpt) error { return nil } // Remove stops monitoring the path for changes. // @@ -61,6 +200,6 @@ func (w *Watcher) Add(name string) error { // /tmp/dir and /tmp/dir/subdir then you will need to remove both. // // Removing a path that has not yet been added returns [ErrNonExistentWatch]. -func (w *Watcher) Remove(name string) error { - return nil -} +// +// Returns nil if [Watcher.Close] was called. +func (w *Watcher) Remove(name string) error { return nil } diff --git a/vendor/github.com/fsnotify/fsnotify/backend_windows.go b/vendor/github.com/fsnotify/fsnotify/backend_windows.go index ae392867c..9bc91e5d6 100644 --- a/vendor/github.com/fsnotify/fsnotify/backend_windows.go +++ b/vendor/github.com/fsnotify/fsnotify/backend_windows.go @@ -1,6 +1,13 @@ //go:build windows // +build windows +// Windows backend based on ReadDirectoryChangesW() +// +// https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-readdirectorychangesw +// +// Note: the documentation on the Watcher type and methods is generated from +// mkdoc.zsh + package fsnotify import ( @@ -27,9 +34,9 @@ import ( // When a file is removed a Remove event won't be emitted until all file // descriptors are closed, and deletes will always emit a Chmod. For example: // -// fp := os.Open("file") -// os.Remove("file") // Triggers Chmod -// fp.Close() // Triggers Remove +// fp := os.Open("file") +// os.Remove("file") // Triggers Chmod +// fp.Close() // Triggers Remove // // This is the event that inotify sends, so not much can be changed about this. // @@ -43,16 +50,16 @@ import ( // // To increase them you can use sysctl or write the value to the /proc file: // -// # Default values on Linux 5.18 -// sysctl fs.inotify.max_user_watches=124983 -// sysctl fs.inotify.max_user_instances=128 +// # Default values on Linux 5.18 +// sysctl fs.inotify.max_user_watches=124983 +// sysctl fs.inotify.max_user_instances=128 // // To make the changes persist on reboot edit /etc/sysctl.conf or // /usr/lib/sysctl.d/50-default.conf (details differ per Linux distro; check // your distro's documentation): // -// fs.inotify.max_user_watches=124983 -// fs.inotify.max_user_instances=128 +// fs.inotify.max_user_watches=124983 +// fs.inotify.max_user_instances=128 // // Reaching the limit will result in a "no space left on device" or "too many open // files" error. @@ -68,14 +75,20 @@ import ( // control the maximum number of open files, as well as /etc/login.conf on BSD // systems. // -// # macOS notes +// # Windows notes // -// Spotlight indexing on macOS can result in multiple events (see [#15]). A -// temporary workaround is to add your folder(s) to the "Spotlight Privacy -// Settings" until we have a native FSEvents implementation (see [#11]). +// Paths can be added as "C:\path\to\dir", but forward slashes +// ("C:/path/to/dir") will also work. // -// [#11]: https://github.com/fsnotify/fsnotify/issues/11 -// [#15]: https://github.com/fsnotify/fsnotify/issues/15 +// When a watched directory is removed it will always send an event for the +// directory itself, but may not send events for all files in that directory. +// Sometimes it will send events for all times, sometimes it will send no +// events, and often only for some files. +// +// The default ReadDirectoryChangesW() buffer size is 64K, which is the largest +// value that is guaranteed to work with SMB filesystems. If you have many +// events in quick succession this may not be enough, and you will have to use +// [WithBufferSize] to increase the value. type Watcher struct { // Events sends the filesystem change events. // @@ -102,31 +115,52 @@ type Watcher struct { // initiated by the user may show up as one or multiple // writes, depending on when the system syncs things to // disk. For example when compiling a large Go program - // you may get hundreds of Write events, so you - // probably want to wait until you've stopped receiving - // them (see the dedup example in cmd/fsnotify). + // you may get hundreds of Write events, and you may + // want to wait until you've stopped receiving them + // (see the dedup example in cmd/fsnotify). + // + // Some systems may send Write event for directories + // when the directory content changes. // // fsnotify.Chmod Attributes were changed. On Linux this is also sent // when a file is removed (or more accurately, when a // link to an inode is removed). On kqueue it's sent - // and on kqueue when a file is truncated. On Windows - // it's never sent. + // when a file is truncated. On Windows it's never + // sent. Events chan Event // Errors sends any errors. + // + // ErrEventOverflow is used to indicate there are too many events: + // + // - inotify: There are too many queued events (fs.inotify.max_queued_events sysctl) + // - windows: The buffer size is too small; WithBufferSize() can be used to increase it. + // - kqueue, fen: Not used. Errors chan error port windows.Handle // Handle to completion port input chan *input // Inputs to the reader are sent on this channel quit chan chan<- error - mu sync.Mutex // Protects access to watches, isClosed - watches watchMap // Map of watches (key: i-number) - isClosed bool // Set to true when Close() is first called + mu sync.Mutex // Protects access to watches, closed + watches watchMap // Map of watches (key: i-number) + closed bool // Set to true when Close() is first called } // NewWatcher creates a new Watcher. func NewWatcher() (*Watcher, error) { + return NewBufferedWatcher(50) +} + +// NewBufferedWatcher creates a new Watcher with a buffered Watcher.Events +// channel. +// +// The main use case for this is situations with a very large number of events +// where the kernel buffer size can't be increased (e.g. due to lack of +// permissions). An unbuffered Watcher will perform better for almost all use +// cases, and whenever possible you will be better off increasing the kernel +// buffers instead of adding a large userspace buffer. +func NewBufferedWatcher(sz uint) (*Watcher, error) { port, err := windows.CreateIoCompletionPort(windows.InvalidHandle, 0, 0, 0) if err != nil { return nil, os.NewSyscallError("CreateIoCompletionPort", err) @@ -135,7 +169,7 @@ func NewWatcher() (*Watcher, error) { port: port, watches: make(watchMap), input: make(chan *input, 1), - Events: make(chan Event, 50), + Events: make(chan Event, sz), Errors: make(chan error), quit: make(chan chan<- error, 1), } @@ -143,6 +177,12 @@ func NewWatcher() (*Watcher, error) { return w, nil } +func (w *Watcher) isClosed() bool { + w.mu.Lock() + defer w.mu.Unlock() + return w.closed +} + func (w *Watcher) sendEvent(name string, mask uint64) bool { if mask == 0 { return false @@ -167,14 +207,14 @@ func (w *Watcher) sendError(err error) bool { return false } -// Close removes all watches and closes the events channel. +// Close removes all watches and closes the Events channel. func (w *Watcher) Close() error { - w.mu.Lock() - if w.isClosed { - w.mu.Unlock() + if w.isClosed() { return nil } - w.isClosed = true + + w.mu.Lock() + w.closed = true w.mu.Unlock() // Send "quit" message to the reader goroutine @@ -188,17 +228,21 @@ func (w *Watcher) Close() error { // Add starts monitoring the path for changes. // -// A path can only be watched once; attempting to watch it more than once will -// return an error. Paths that do not yet exist on the filesystem cannot be -// added. A watch will be automatically removed if the path is deleted. +// A path can only be watched once; watching it more than once is a no-op and will +// not return an error. Paths that do not yet exist on the filesystem cannot be +// watched. // -// A path will remain watched if it gets renamed to somewhere else on the same -// filesystem, but the monitor will get removed if the path gets deleted and -// re-created, or if it's moved to a different filesystem. +// A watch will be automatically removed if the watched path is deleted or +// renamed. The exception is the Windows backend, which doesn't remove the +// watcher on renames. // // Notifications on network filesystems (NFS, SMB, FUSE, etc.) or special // filesystems (/proc, /sys, etc.) generally don't work. // +// Returns [ErrClosed] if [Watcher.Close] was called. +// +// See [Watcher.AddWith] for a version that allows adding options. +// // # Watching directories // // All files in a directory are monitored, including new files that are created @@ -208,27 +252,41 @@ func (w *Watcher) Close() error { // # Watching files // // Watching individual files (rather than directories) is generally not -// recommended as many tools update files atomically. Instead of "just" writing -// to the file a temporary file will be written to first, and if successful the -// temporary file is moved to to destination removing the original, or some -// variant thereof. The watcher on the original file is now lost, as it no -// longer exists. -// -// Instead, watch the parent directory and use Event.Name to filter out files -// you're not interested in. There is an example of this in [cmd/fsnotify/file.go]. -func (w *Watcher) Add(name string) error { - w.mu.Lock() - if w.isClosed { - w.mu.Unlock() - return errors.New("watcher already closed") +// recommended as many programs (especially editors) update files atomically: it +// will write to a temporary file which is then moved to to destination, +// overwriting the original (or some variant thereof). The watcher on the +// original file is now lost, as that no longer exists. +// +// The upshot of this is that a power failure or crash won't leave a +// half-written file. +// +// Watch the parent directory and use Event.Name to filter out files you're not +// interested in. There is an example of this in cmd/fsnotify/file.go. +func (w *Watcher) Add(name string) error { return w.AddWith(name) } + +// AddWith is like [Watcher.Add], but allows adding options. When using Add() +// the defaults described below are used. +// +// Possible options are: +// +// - [WithBufferSize] sets the buffer size for the Windows backend; no-op on +// other platforms. The default is 64K (65536 bytes). +func (w *Watcher) AddWith(name string, opts ...addOpt) error { + if w.isClosed() { + return ErrClosed + } + + with := getOptions(opts...) + if with.bufsize < 4096 { + return fmt.Errorf("fsnotify.WithBufferSize: buffer size cannot be smaller than 4096 bytes") } - w.mu.Unlock() in := &input{ - op: opAddWatch, - path: filepath.Clean(name), - flags: sysFSALLEVENTS, - reply: make(chan error), + op: opAddWatch, + path: filepath.Clean(name), + flags: sysFSALLEVENTS, + reply: make(chan error), + bufsize: with.bufsize, } w.input <- in if err := w.wakeupReader(); err != nil { @@ -243,7 +301,13 @@ func (w *Watcher) Add(name string) error { // /tmp/dir and /tmp/dir/subdir then you will need to remove both. // // Removing a path that has not yet been added returns [ErrNonExistentWatch]. +// +// Returns nil if [Watcher.Close] was called. func (w *Watcher) Remove(name string) error { + if w.isClosed() { + return nil + } + in := &input{ op: opRemoveWatch, path: filepath.Clean(name), @@ -256,8 +320,15 @@ func (w *Watcher) Remove(name string) error { return <-in.reply } -// WatchList returns all paths added with [Add] (and are not yet removed). +// WatchList returns all paths explicitly added with [Watcher.Add] (and are not +// yet removed). +// +// Returns nil if [Watcher.Close] was called. func (w *Watcher) WatchList() []string { + if w.isClosed() { + return nil + } + w.mu.Lock() defer w.mu.Unlock() @@ -279,7 +350,6 @@ func (w *Watcher) WatchList() []string { // This should all be removed at some point, and just use windows.FILE_NOTIFY_* const ( sysFSALLEVENTS = 0xfff - sysFSATTRIB = 0x4 sysFSCREATE = 0x100 sysFSDELETE = 0x200 sysFSDELETESELF = 0x400 @@ -305,9 +375,6 @@ func (w *Watcher) newEvent(name string, mask uint32) Event { if mask&sysFSMOVE == sysFSMOVE || mask&sysFSMOVESELF == sysFSMOVESELF || mask&sysFSMOVEDFROM == sysFSMOVEDFROM { e.Op |= Rename } - if mask&sysFSATTRIB == sysFSATTRIB { - e.Op |= Chmod - } return e } @@ -321,10 +388,11 @@ const ( ) type input struct { - op int - path string - flags uint32 - reply chan error + op int + path string + flags uint32 + bufsize int + reply chan error } type inode struct { @@ -334,13 +402,14 @@ type inode struct { } type watch struct { - ov windows.Overlapped - ino *inode // i-number - path string // Directory path - mask uint64 // Directory itself is being watched with these notify flags - names map[string]uint64 // Map of names being watched and their notify flags - rename string // Remembers the old name while renaming a file - buf [65536]byte // 64K buffer + ov windows.Overlapped + ino *inode // i-number + recurse bool // Recursive watch? + path string // Directory path + mask uint64 // Directory itself is being watched with these notify flags + names map[string]uint64 // Map of names being watched and their notify flags + rename string // Remembers the old name while renaming a file + buf []byte // buffer, allocated later } type ( @@ -413,7 +482,10 @@ func (m watchMap) set(ino *inode, watch *watch) { } // Must run within the I/O thread. -func (w *Watcher) addWatch(pathname string, flags uint64) error { +func (w *Watcher) addWatch(pathname string, flags uint64, bufsize int) error { + //pathname, recurse := recursivePath(pathname) + recurse := false + dir, err := w.getDir(pathname) if err != nil { return err @@ -433,9 +505,11 @@ func (w *Watcher) addWatch(pathname string, flags uint64) error { return os.NewSyscallError("CreateIoCompletionPort", err) } watchEntry = &watch{ - ino: ino, - path: dir, - names: make(map[string]uint64), + ino: ino, + path: dir, + names: make(map[string]uint64), + recurse: recurse, + buf: make([]byte, bufsize), } w.mu.Lock() w.watches.set(ino, watchEntry) @@ -465,6 +539,8 @@ func (w *Watcher) addWatch(pathname string, flags uint64) error { // Must run within the I/O thread. func (w *Watcher) remWatch(pathname string) error { + pathname, recurse := recursivePath(pathname) + dir, err := w.getDir(pathname) if err != nil { return err @@ -478,6 +554,10 @@ func (w *Watcher) remWatch(pathname string) error { watch := w.watches.get(ino) w.mu.Unlock() + if recurse && !watch.recurse { + return fmt.Errorf("can't use \\... with non-recursive watch %q", pathname) + } + err = windows.CloseHandle(ino.handle) if err != nil { w.sendError(os.NewSyscallError("CloseHandle", err)) @@ -535,8 +615,11 @@ func (w *Watcher) startRead(watch *watch) error { return nil } - rdErr := windows.ReadDirectoryChanges(watch.ino.handle, &watch.buf[0], - uint32(unsafe.Sizeof(watch.buf)), false, mask, nil, &watch.ov, 0) + // We need to pass the array, rather than the slice. + hdr := (*reflect.SliceHeader)(unsafe.Pointer(&watch.buf)) + rdErr := windows.ReadDirectoryChanges(watch.ino.handle, + (*byte)(unsafe.Pointer(hdr.Data)), uint32(hdr.Len), + watch.recurse, mask, nil, &watch.ov, 0) if rdErr != nil { err := os.NewSyscallError("ReadDirectoryChanges", rdErr) if rdErr == windows.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 { @@ -563,9 +646,8 @@ func (w *Watcher) readEvents() { runtime.LockOSThread() for { + // This error is handled after the watch == nil check below. qErr := windows.GetQueuedCompletionStatus(w.port, &n, &key, &ov, windows.INFINITE) - // This error is handled after the watch == nil check below. NOTE: this - // seems odd, note sure if it's correct. watch := (*watch)(unsafe.Pointer(ov)) if watch == nil { @@ -595,7 +677,7 @@ func (w *Watcher) readEvents() { case in := <-w.input: switch in.op { case opAddWatch: - in.reply <- w.addWatch(in.path, uint64(in.flags)) + in.reply <- w.addWatch(in.path, uint64(in.flags), in.bufsize) case opRemoveWatch: in.reply <- w.remWatch(in.path) } @@ -605,6 +687,8 @@ func (w *Watcher) readEvents() { } switch qErr { + case nil: + // No error case windows.ERROR_MORE_DATA: if watch == nil { w.sendError(errors.New("ERROR_MORE_DATA has unexpectedly null lpOverlapped buffer")) @@ -626,13 +710,12 @@ func (w *Watcher) readEvents() { default: w.sendError(os.NewSyscallError("GetQueuedCompletionPort", qErr)) continue - case nil: } var offset uint32 for { if n == 0 { - w.sendError(errors.New("short read in readEvents()")) + w.sendError(ErrEventOverflow) break } @@ -703,8 +786,9 @@ func (w *Watcher) readEvents() { // Error! if offset >= n { + //lint:ignore ST1005 Windows should be capitalized w.sendError(errors.New( - "Windows system assumed buffer larger than it is, events have likely been missed.")) + "Windows system assumed buffer larger than it is, events have likely been missed")) break } } @@ -720,9 +804,6 @@ func (w *Watcher) toWindowsFlags(mask uint64) uint32 { if mask&sysFSMODIFY != 0 { m |= windows.FILE_NOTIFY_CHANGE_LAST_WRITE } - if mask&sysFSATTRIB != 0 { - m |= windows.FILE_NOTIFY_CHANGE_ATTRIBUTES - } if mask&(sysFSMOVE|sysFSCREATE|sysFSDELETE) != 0 { m |= windows.FILE_NOTIFY_CHANGE_FILE_NAME | windows.FILE_NOTIFY_CHANGE_DIR_NAME } diff --git a/vendor/github.com/fsnotify/fsnotify/fsnotify.go b/vendor/github.com/fsnotify/fsnotify/fsnotify.go index 30a5bf0f0..24c99cc49 100644 --- a/vendor/github.com/fsnotify/fsnotify/fsnotify.go +++ b/vendor/github.com/fsnotify/fsnotify/fsnotify.go @@ -1,13 +1,18 @@ -//go:build !plan9 -// +build !plan9 - // Package fsnotify provides a cross-platform interface for file system // notifications. +// +// Currently supported systems: +// +// Linux 2.6.32+ via inotify +// BSD, macOS via kqueue +// Windows via ReadDirectoryChangesW +// illumos via FEN package fsnotify import ( "errors" "fmt" + "path/filepath" "strings" ) @@ -33,34 +38,52 @@ type Op uint32 // The operations fsnotify can trigger; see the documentation on [Watcher] for a // full description, and check them with [Event.Has]. const ( + // A new pathname was created. Create Op = 1 << iota + + // The pathname was written to; this does *not* mean the write has finished, + // and a write can be followed by more writes. Write + + // The path was removed; any watches on it will be removed. Some "remove" + // operations may trigger a Rename if the file is actually moved (for + // example "remove to trash" is often a rename). Remove + + // The path was renamed to something else; any watched on it will be + // removed. Rename + + // File attributes were changed. + // + // It's generally not recommended to take action on this event, as it may + // get triggered very frequently by some software. For example, Spotlight + // indexing on macOS, anti-virus software, backup software, etc. Chmod ) -// Common errors that can be reported by a watcher +// Common errors that can be reported. var ( - ErrNonExistentWatch = errors.New("can't remove non-existent watcher") - ErrEventOverflow = errors.New("fsnotify queue overflow") + ErrNonExistentWatch = errors.New("fsnotify: can't remove non-existent watch") + ErrEventOverflow = errors.New("fsnotify: queue or buffer overflow") + ErrClosed = errors.New("fsnotify: watcher already closed") ) -func (op Op) String() string { +func (o Op) String() string { var b strings.Builder - if op.Has(Create) { + if o.Has(Create) { b.WriteString("|CREATE") } - if op.Has(Remove) { + if o.Has(Remove) { b.WriteString("|REMOVE") } - if op.Has(Write) { + if o.Has(Write) { b.WriteString("|WRITE") } - if op.Has(Rename) { + if o.Has(Rename) { b.WriteString("|RENAME") } - if op.Has(Chmod) { + if o.Has(Chmod) { b.WriteString("|CHMOD") } if b.Len() == 0 { @@ -70,7 +93,7 @@ func (op Op) String() string { } // Has reports if this operation has the given operation. -func (o Op) Has(h Op) bool { return o&h == h } +func (o Op) Has(h Op) bool { return o&h != 0 } // Has reports if this event has the given operation. func (e Event) Has(op Op) bool { return e.Op.Has(op) } @@ -79,3 +102,45 @@ func (e Event) Has(op Op) bool { return e.Op.Has(op) } func (e Event) String() string { return fmt.Sprintf("%-13s %q", e.Op.String(), e.Name) } + +type ( + addOpt func(opt *withOpts) + withOpts struct { + bufsize int + } +) + +var defaultOpts = withOpts{ + bufsize: 65536, // 64K +} + +func getOptions(opts ...addOpt) withOpts { + with := defaultOpts + for _, o := range opts { + o(&with) + } + return with +} + +// WithBufferSize sets the [ReadDirectoryChangesW] buffer size. +// +// This only has effect on Windows systems, and is a no-op for other backends. +// +// The default value is 64K (65536 bytes) which is the highest value that works +// on all filesystems and should be enough for most applications, but if you +// have a large burst of events it may not be enough. You can increase it if +// you're hitting "queue or buffer overflow" errors ([ErrEventOverflow]). +// +// [ReadDirectoryChangesW]: https://learn.microsoft.com/en-gb/windows/win32/api/winbase/nf-winbase-readdirectorychangesw +func WithBufferSize(bytes int) addOpt { + return func(opt *withOpts) { opt.bufsize = bytes } +} + +// Check if this path is recursive (ends with "/..." or "\..."), and return the +// path with the /... stripped. +func recursivePath(path string) (string, bool) { + if filepath.Base(path) == "..." { + return filepath.Dir(path), true + } + return path, false +} diff --git a/vendor/github.com/fsnotify/fsnotify/mkdoc.zsh b/vendor/github.com/fsnotify/fsnotify/mkdoc.zsh index b09ef7683..99012ae65 100644 --- a/vendor/github.com/fsnotify/fsnotify/mkdoc.zsh +++ b/vendor/github.com/fsnotify/fsnotify/mkdoc.zsh @@ -2,8 +2,8 @@ [ "${ZSH_VERSION:-}" = "" ] && echo >&2 "Only works with zsh" && exit 1 setopt err_exit no_unset pipefail extended_glob -# Simple script to update the godoc comments on all watchers. Probably took me -# more time to write this than doing it manually, but ah well 🙃 +# Simple script to update the godoc comments on all watchers so you don't need +# to update the same comment 5 times. watcher=$(<

- - Build Status - Go Reference diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/binary.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/binary.go index 29bdded3e..f1e944987 100644 --- a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/binary.go +++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/binary.go @@ -150,32 +150,34 @@ func Marc(raw []byte, limit uint32) bool { } // Glb matches a glTF model format file. -// GLB is the binary file format representation of 3D models save in +// GLB is the binary file format representation of 3D models saved in // the GL transmission Format (glTF). -// see more: https://docs.fileformat.com/3d/glb/ -// https://www.iana.org/assignments/media-types/model/gltf-binary -// GLB file format is based on little endian and its header structure -// show below: +// GLB uses little endian and its header structure is as follows: // -// <-- 12-byte header --> -// | magic | version | length | -// | (uint32) | (uint32) | (uint32) | -// | \x67\x6C\x54\x46 | \x01\x00\x00\x00 | ... | -// | g l T F | 1 | ... | +// <-- 12-byte header --> +// | magic | version | length | +// | (uint32) | (uint32) | (uint32) | +// | \x67\x6C\x54\x46 | \x01\x00\x00\x00 | ... | +// | g l T F | 1 | ... | +// +// Visit [glTF specification] and [IANA glTF entry] for more details. +// +// [glTF specification]: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html +// [IANA glTF entry]: https://www.iana.org/assignments/media-types/model/gltf-binary var Glb = prefix([]byte("\x67\x6C\x54\x46\x02\x00\x00\x00"), []byte("\x67\x6C\x54\x46\x01\x00\x00\x00")) // TzIf matches a Time Zone Information Format (TZif) file. // See more: https://tools.ietf.org/id/draft-murchison-tzdist-tzif-00.html#rfc.section.3 // Its header structure is shown below: -// +---------------+---+ -// | magic (4) | <-+-- version (1) -// +---------------+---+---------------------------------------+ -// | [unused - reserved for future use] (15) | -// +---------------+---------------+---------------+-----------+ -// | isutccnt (4) | isstdcnt (4) | leapcnt (4) | -// +---------------+---------------+---------------+ -// | timecnt (4) | typecnt (4) | charcnt (4) | +// +---------------+---+ +// | magic (4) | <-+-- version (1) +// +---------------+---+---------------------------------------+ +// | [unused - reserved for future use] (15) | +// +---------------+---------------+---------------+-----------+ +// | isutccnt (4) | isstdcnt (4) | leapcnt (4) | +// +---------------+---------------+---------------+ +// | timecnt (4) | typecnt (4) | charcnt (4) | func TzIf(raw []byte, limit uint32) bool { // File is at least 44 bytes (header size). if len(raw) < 44 { diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/magic.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/magic.go index 466058fbe..34b84f401 100644 --- a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/magic.go +++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/magic.go @@ -177,7 +177,9 @@ func newXMLSig(localName, xmlns string) xmlSig { // and, optionally, followed by the arguments for the interpreter. // // Ex: -// #! /usr/bin/env php +// +// #! /usr/bin/env php +// // /usr/bin/env is the interpreter, php is the first and only argument. func shebang(sigs ...[]byte) Detector { return func(raw []byte, limit uint32) bool { diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/text_csv.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/text_csv.go index 6a1561923..84ed64928 100644 --- a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/text_csv.go +++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/text_csv.go @@ -3,6 +3,7 @@ package magic import ( "bytes" "encoding/csv" + "errors" "io" ) @@ -19,12 +20,23 @@ func Tsv(raw []byte, limit uint32) bool { func sv(in []byte, comma rune, limit uint32) bool { r := csv.NewReader(dropLastLine(in, limit)) r.Comma = comma - r.TrimLeadingSpace = true + r.ReuseRecord = true r.LazyQuotes = true r.Comment = '#' - lines, err := r.ReadAll() - return err == nil && r.FieldsPerRecord > 1 && len(lines) > 1 + lines := 0 + for { + _, err := r.Read() + if errors.Is(err, io.EOF) { + break + } + if err != nil { + return false + } + lines++ + } + + return r.FieldsPerRecord > 1 && lines > 1 } // dropLastLine drops the last incomplete line from b. diff --git a/vendor/github.com/gabriel-vasile/mimetype/mimetype.go b/vendor/github.com/gabriel-vasile/mimetype/mimetype.go index 08e68e334..1b5909b75 100644 --- a/vendor/github.com/gabriel-vasile/mimetype/mimetype.go +++ b/vendor/github.com/gabriel-vasile/mimetype/mimetype.go @@ -39,7 +39,8 @@ func Detect(in []byte) *MIME { // // DetectReader assumes the reader offset is at the start. If the input is an // io.ReadSeeker you previously read from, it should be rewinded before detection: -// reader.Seek(0, io.SeekStart) +// +// reader.Seek(0, io.SeekStart) func DetectReader(r io.Reader) (*MIME, error) { var in []byte var err error diff --git a/vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md b/vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md index cdec4e674..5ec6f6b65 100644 --- a/vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md +++ b/vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md @@ -1,4 +1,4 @@ -## 172 Supported MIME types +## 173 Supported MIME types This file is automatically generated when running tests. Do not edit manually. Extension | MIME type | Aliases diff --git a/vendor/github.com/go-logr/logr/README.md b/vendor/github.com/go-logr/logr/README.md index ab5931181..a8c29bfbd 100644 --- a/vendor/github.com/go-logr/logr/README.md +++ b/vendor/github.com/go-logr/logr/README.md @@ -1,6 +1,7 @@ # A minimal logging API for Go [![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/logr.svg)](https://pkg.go.dev/github.com/go-logr/logr) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/go-logr/logr/badge)](https://securityscorecards.dev/viewer/?platform=github.com&org=go-logr&repo=logr) logr offers an(other) opinion on how Go programs and libraries can do logging without becoming coupled to a particular logging implementation. This is not @@ -73,6 +74,29 @@ received: If the Go standard library had defined an interface for logging, this project probably would not be needed. Alas, here we are. +When the Go developers started developing such an interface with +[slog](https://github.com/golang/go/issues/56345), they adopted some of the +logr design but also left out some parts and changed others: + +| Feature | logr | slog | +|---------|------|------| +| High-level API | `Logger` (passed by value) | `Logger` (passed by [pointer](https://github.com/golang/go/issues/59126)) | +| Low-level API | `LogSink` | `Handler` | +| Stack unwinding | done by `LogSink` | done by `Logger` | +| Skipping helper functions | `WithCallDepth`, `WithCallStackHelper` | [not supported by Logger](https://github.com/golang/go/issues/59145) | +| Generating a value for logging on demand | `Marshaler` | `LogValuer` | +| Log levels | >= 0, higher meaning "less important" | positive and negative, with 0 for "info" and higher meaning "more important" | +| Error log entries | always logged, don't have a verbosity level | normal log entries with level >= `LevelError` | +| Passing logger via context | `NewContext`, `FromContext` | no API | +| Adding a name to a logger | `WithName` | no API | +| Modify verbosity of log entries in a call chain | `V` | no API | +| Grouping of key/value pairs | not supported | `WithGroup`, `GroupValue` | + +The high-level slog API is explicitly meant to be one of many different APIs +that can be layered on top of a shared `slog.Handler`. logr is one such +alternative API, with [interoperability](#slog-interoperability) provided by the [`slogr`](slogr) +package. + ### Inspiration Before you consider this package, please read [this blog post by the @@ -118,6 +142,91 @@ There are implementations for the following logging libraries: - **github.com/go-kit/log**: [gokitlogr](https://github.com/tonglil/gokitlogr) (also compatible with github.com/go-kit/kit/log since v0.12.0) - **bytes.Buffer** (writing to a buffer): [bufrlogr](https://github.com/tonglil/buflogr) (useful for ensuring values were logged, like during testing) +## slog interoperability + +Interoperability goes both ways, using the `logr.Logger` API with a `slog.Handler` +and using the `slog.Logger` API with a `logr.LogSink`. [slogr](./slogr) provides `NewLogr` and +`NewSlogHandler` API calls to convert between a `logr.Logger` and a `slog.Handler`. +As usual, `slog.New` can be used to wrap such a `slog.Handler` in the high-level +slog API. `slogr` itself leaves that to the caller. + +## Using a `logr.Sink` as backend for slog + +Ideally, a logr sink implementation should support both logr and slog by +implementing both the normal logr interface(s) and `slogr.SlogSink`. Because +of a conflict in the parameters of the common `Enabled` method, it is [not +possible to implement both slog.Handler and logr.Sink in the same +type](https://github.com/golang/go/issues/59110). + +If both are supported, log calls can go from the high-level APIs to the backend +without the need to convert parameters. `NewLogr` and `NewSlogHandler` can +convert back and forth without adding additional wrappers, with one exception: +when `Logger.V` was used to adjust the verbosity for a `slog.Handler`, then +`NewSlogHandler` has to use a wrapper which adjusts the verbosity for future +log calls. + +Such an implementation should also support values that implement specific +interfaces from both packages for logging (`logr.Marshaler`, `slog.LogValuer`, +`slog.GroupValue`). logr does not convert those. + +Not supporting slog has several drawbacks: +- Recording source code locations works correctly if the handler gets called + through `slog.Logger`, but may be wrong in other cases. That's because a + `logr.Sink` does its own stack unwinding instead of using the program counter + provided by the high-level API. +- slog levels <= 0 can be mapped to logr levels by negating the level without a + loss of information. But all slog levels > 0 (e.g. `slog.LevelWarning` as + used by `slog.Logger.Warn`) must be mapped to 0 before calling the sink + because logr does not support "more important than info" levels. +- The slog group concept is supported by prefixing each key in a key/value + pair with the group names, separated by a dot. For structured output like + JSON it would be better to group the key/value pairs inside an object. +- Special slog values and interfaces don't work as expected. +- The overhead is likely to be higher. + +These drawbacks are severe enough that applications using a mixture of slog and +logr should switch to a different backend. + +## Using a `slog.Handler` as backend for logr + +Using a plain `slog.Handler` without support for logr works better than the +other direction: +- All logr verbosity levels can be mapped 1:1 to their corresponding slog level + by negating them. +- Stack unwinding is done by the `slogr.SlogSink` and the resulting program + counter is passed to the `slog.Handler`. +- Names added via `Logger.WithName` are gathered and recorded in an additional + attribute with `logger` as key and the names separated by slash as value. +- `Logger.Error` is turned into a log record with `slog.LevelError` as level + and an additional attribute with `err` as key, if an error was provided. + +The main drawback is that `logr.Marshaler` will not be supported. Types should +ideally support both `logr.Marshaler` and `slog.Valuer`. If compatibility +with logr implementations without slog support is not important, then +`slog.Valuer` is sufficient. + +## Context support for slog + +Storing a logger in a `context.Context` is not supported by +slog. `logr.NewContext` and `logr.FromContext` can be used with slog like this +to fill this gap: + + func HandlerFromContext(ctx context.Context) slog.Handler { + logger, err := logr.FromContext(ctx) + if err == nil { + return slogr.NewSlogHandler(logger) + } + return slog.Default().Handler() + } + + func ContextWithHandler(ctx context.Context, handler slog.Handler) context.Context { + return logr.NewContext(ctx, slogr.NewLogr(handler)) + } + +The downside is that storing and retrieving a `slog.Handler` needs more +allocations compared to using a `logr.Logger`. Therefore the recommendation is +to use the `logr.Logger` API in code which uses contextual logging. + ## FAQ ### Conceptual @@ -241,7 +350,9 @@ Otherwise, you can start out with `0` as "you always want to see this", Then gradually choose levels in between as you need them, working your way down from 10 (for debug and trace style logs) and up from 1 (for chattier -info-type logs.) +info-type logs). For reference, slog pre-defines -4 for debug logs +(corresponds to 4 in logr), which matches what is +[recommended for Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use). #### How do I choose my keys? diff --git a/vendor/github.com/go-logr/logr/SECURITY.md b/vendor/github.com/go-logr/logr/SECURITY.md new file mode 100644 index 000000000..1ca756fc7 --- /dev/null +++ b/vendor/github.com/go-logr/logr/SECURITY.md @@ -0,0 +1,18 @@ +# Security Policy + +If you have discovered a security vulnerability in this project, please report it +privately. **Do not disclose it as a public issue.** This gives us time to work with you +to fix the issue before public exposure, reducing the chance that the exploit will be +used before a patch is released. + +You may submit the report in the following ways: + +- send an email to go-logr-security@googlegroups.com +- send us a [private vulnerability report](https://github.com/go-logr/logr/security/advisories/new) + +Please provide the following information in your report: + +- A description of the vulnerability and its impact +- How to reproduce the issue + +We ask that you give us 90 days to work on a fix before public exposure. diff --git a/vendor/github.com/go-logr/logr/funcr/funcr.go b/vendor/github.com/go-logr/logr/funcr/funcr.go index e52f0cd01..12e5807cc 100644 --- a/vendor/github.com/go-logr/logr/funcr/funcr.go +++ b/vendor/github.com/go-logr/logr/funcr/funcr.go @@ -116,17 +116,17 @@ type Options struct { // Equivalent hooks are offered for key-value pairs saved via // logr.Logger.WithValues or Formatter.AddValues (see RenderValuesHook) and // for user-provided pairs (see RenderArgsHook). - RenderBuiltinsHook func(kvList []interface{}) []interface{} + RenderBuiltinsHook func(kvList []any) []any // RenderValuesHook is the same as RenderBuiltinsHook, except that it is // only called for key-value pairs saved via logr.Logger.WithValues. See // RenderBuiltinsHook for more details. - RenderValuesHook func(kvList []interface{}) []interface{} + RenderValuesHook func(kvList []any) []any // RenderArgsHook is the same as RenderBuiltinsHook, except that it is only // called for key-value pairs passed directly to Info and Error. See // RenderBuiltinsHook for more details. - RenderArgsHook func(kvList []interface{}) []interface{} + RenderArgsHook func(kvList []any) []any // MaxLogDepth tells funcr how many levels of nested fields (e.g. a struct // that contains a struct, etc.) it may log. Every time it finds a struct, @@ -163,7 +163,7 @@ func (l fnlogger) WithName(name string) logr.LogSink { return &l } -func (l fnlogger) WithValues(kvList ...interface{}) logr.LogSink { +func (l fnlogger) WithValues(kvList ...any) logr.LogSink { l.Formatter.AddValues(kvList) return &l } @@ -173,12 +173,12 @@ func (l fnlogger) WithCallDepth(depth int) logr.LogSink { return &l } -func (l fnlogger) Info(level int, msg string, kvList ...interface{}) { +func (l fnlogger) Info(level int, msg string, kvList ...any) { prefix, args := l.FormatInfo(level, msg, kvList) l.write(prefix, args) } -func (l fnlogger) Error(err error, msg string, kvList ...interface{}) { +func (l fnlogger) Error(err error, msg string, kvList ...any) { prefix, args := l.FormatError(err, msg, kvList) l.write(prefix, args) } @@ -229,7 +229,7 @@ func newFormatter(opts Options, outfmt outputFormat) Formatter { type Formatter struct { outputFormat outputFormat prefix string - values []interface{} + values []any valuesStr string depth int opts *Options @@ -246,10 +246,10 @@ const ( ) // PseudoStruct is a list of key-value pairs that gets logged as a struct. -type PseudoStruct []interface{} +type PseudoStruct []any // render produces a log line, ready to use. -func (f Formatter) render(builtins, args []interface{}) string { +func (f Formatter) render(builtins, args []any) string { // Empirically bytes.Buffer is faster than strings.Builder for this. buf := bytes.NewBuffer(make([]byte, 0, 1024)) if f.outputFormat == outputJSON { @@ -292,7 +292,7 @@ func (f Formatter) render(builtins, args []interface{}) string { // This function returns a potentially modified version of kvList, which // ensures that there is a value for every key (adding a value if needed) and // that each key is a string (substituting a key if needed). -func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing bool, escapeKeys bool) []interface{} { +func (f Formatter) flatten(buf *bytes.Buffer, kvList []any, continuing bool, escapeKeys bool) []any { // This logic overlaps with sanitize() but saves one type-cast per key, // which can be measurable. if len(kvList)%2 != 0 { @@ -334,7 +334,7 @@ func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing b return kvList } -func (f Formatter) pretty(value interface{}) string { +func (f Formatter) pretty(value any) string { return f.prettyWithFlags(value, 0, 0) } @@ -343,7 +343,7 @@ const ( ) // TODO: This is not fast. Most of the overhead goes here. -func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) string { +func (f Formatter) prettyWithFlags(value any, flags uint32, depth int) string { if depth > f.opts.MaxLogDepth { return `""` } @@ -614,7 +614,7 @@ func isEmpty(v reflect.Value) bool { return false } -func invokeMarshaler(m logr.Marshaler) (ret interface{}) { +func invokeMarshaler(m logr.Marshaler) (ret any) { defer func() { if r := recover(); r != nil { ret = fmt.Sprintf("", r) @@ -675,12 +675,12 @@ func (f Formatter) caller() Caller { const noValue = "" -func (f Formatter) nonStringKey(v interface{}) string { +func (f Formatter) nonStringKey(v any) string { return fmt.Sprintf("", f.snippet(v)) } // snippet produces a short snippet string of an arbitrary value. -func (f Formatter) snippet(v interface{}) string { +func (f Formatter) snippet(v any) string { const snipLen = 16 snip := f.pretty(v) @@ -693,7 +693,7 @@ func (f Formatter) snippet(v interface{}) string { // sanitize ensures that a list of key-value pairs has a value for every key // (adding a value if needed) and that each key is a string (substituting a key // if needed). -func (f Formatter) sanitize(kvList []interface{}) []interface{} { +func (f Formatter) sanitize(kvList []any) []any { if len(kvList)%2 != 0 { kvList = append(kvList, noValue) } @@ -727,8 +727,8 @@ func (f Formatter) GetDepth() int { // FormatInfo renders an Info log message into strings. The prefix will be // empty when no names were set (via AddNames), or when the output is // configured for JSON. -func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (prefix, argsStr string) { - args := make([]interface{}, 0, 64) // using a constant here impacts perf +func (f Formatter) FormatInfo(level int, msg string, kvList []any) (prefix, argsStr string) { + args := make([]any, 0, 64) // using a constant here impacts perf prefix = f.prefix if f.outputFormat == outputJSON { args = append(args, "logger", prefix) @@ -745,10 +745,10 @@ func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (pref } // FormatError renders an Error log message into strings. The prefix will be -// empty when no names were set (via AddNames), or when the output is +// empty when no names were set (via AddNames), or when the output is // configured for JSON. -func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (prefix, argsStr string) { - args := make([]interface{}, 0, 64) // using a constant here impacts perf +func (f Formatter) FormatError(err error, msg string, kvList []any) (prefix, argsStr string) { + args := make([]any, 0, 64) // using a constant here impacts perf prefix = f.prefix if f.outputFormat == outputJSON { args = append(args, "logger", prefix) @@ -761,12 +761,12 @@ func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (pre args = append(args, "caller", f.caller()) } args = append(args, "msg", msg) - var loggableErr interface{} + var loggableErr any if err != nil { loggableErr = err.Error() } args = append(args, "error", loggableErr) - return f.prefix, f.render(args, kvList) + return prefix, f.render(args, kvList) } // AddName appends the specified name. funcr uses '/' characters to separate @@ -781,7 +781,7 @@ func (f *Formatter) AddName(name string) { // AddValues adds key-value pairs to the set of saved values to be logged with // each log line. -func (f *Formatter) AddValues(kvList []interface{}) { +func (f *Formatter) AddValues(kvList []any) { // Three slice args forces a copy. n := len(f.values) f.values = append(f.values[:n:n], kvList...) diff --git a/vendor/github.com/go-logr/logr/logr.go b/vendor/github.com/go-logr/logr/logr.go index e027aea3f..2a5075a18 100644 --- a/vendor/github.com/go-logr/logr/logr.go +++ b/vendor/github.com/go-logr/logr/logr.go @@ -127,9 +127,9 @@ limitations under the License. // such a value can call its methods without having to check whether the // instance is ready for use. // -// Calling methods with the null logger (Logger{}) as instance will crash -// because it has no LogSink. Therefore this null logger should never be passed -// around. For cases where passing a logger is optional, a pointer to Logger +// The zero logger (= Logger{}) is identical to Discard() and discards all log +// entries. Code that receives a Logger by value can simply call it, the methods +// will never crash. For cases where passing a logger is optional, a pointer to Logger // should be used. // // # Key Naming Conventions @@ -258,6 +258,12 @@ type Logger struct { // Enabled tests whether this Logger is enabled. For example, commandline // flags might be used to set the logging verbosity and disable some info logs. func (l Logger) Enabled() bool { + // Some implementations of LogSink look at the caller in Enabled (e.g. + // different verbosity levels per package or file), but we only pass one + // CallDepth in (via Init). This means that all calls from Logger to the + // LogSink's Enabled, Info, and Error methods must have the same number of + // frames. In other words, Logger methods can't call other Logger methods + // which call these LogSink methods unless we do it the same in all paths. return l.sink != nil && l.sink.Enabled(l.level) } @@ -267,11 +273,11 @@ func (l Logger) Enabled() bool { // line. The key/value pairs can then be used to add additional variable // information. The key/value pairs must alternate string keys and arbitrary // values. -func (l Logger) Info(msg string, keysAndValues ...interface{}) { +func (l Logger) Info(msg string, keysAndValues ...any) { if l.sink == nil { return } - if l.Enabled() { + if l.sink.Enabled(l.level) { // see comment in Enabled if withHelper, ok := l.sink.(CallStackHelperLogSink); ok { withHelper.GetCallStackHelper()() } @@ -289,7 +295,7 @@ func (l Logger) Info(msg string, keysAndValues ...interface{}) { // while the err argument should be used to attach the actual error that // triggered this log line, if present. The err parameter is optional // and nil may be passed instead of an error instance. -func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) { +func (l Logger) Error(err error, msg string, keysAndValues ...any) { if l.sink == nil { return } @@ -314,9 +320,16 @@ func (l Logger) V(level int) Logger { return l } +// GetV returns the verbosity level of the logger. If the logger's LogSink is +// nil as in the Discard logger, this will always return 0. +func (l Logger) GetV() int { + // 0 if l.sink nil because of the if check in V above. + return l.level +} + // WithValues returns a new Logger instance with additional key/value pairs. // See Info for documentation on how key/value pairs work. -func (l Logger) WithValues(keysAndValues ...interface{}) Logger { +func (l Logger) WithValues(keysAndValues ...any) Logger { if l.sink == nil { return l } @@ -467,15 +480,15 @@ type LogSink interface { // The level argument is provided for optional logging. This method will // only be called when Enabled(level) is true. See Logger.Info for more // details. - Info(level int, msg string, keysAndValues ...interface{}) + Info(level int, msg string, keysAndValues ...any) // Error logs an error, with the given message and key/value pairs as // context. See Logger.Error for more details. - Error(err error, msg string, keysAndValues ...interface{}) + Error(err error, msg string, keysAndValues ...any) // WithValues returns a new LogSink with additional key/value pairs. See // Logger.WithValues for more details. - WithValues(keysAndValues ...interface{}) LogSink + WithValues(keysAndValues ...any) LogSink // WithName returns a new LogSink with the specified name appended. See // Logger.WithName for more details. @@ -546,5 +559,5 @@ type Marshaler interface { // with exported fields // // It may return any value of any type. - MarshalLog() interface{} + MarshalLog() any } diff --git a/vendor/github.com/go-openapi/errors/api.go b/vendor/github.com/go-openapi/errors/api.go index 77f1f92c5..c13f3435f 100644 --- a/vendor/github.com/go-openapi/errors/api.go +++ b/vendor/github.com/go-openapi/errors/api.go @@ -112,7 +112,7 @@ func flattenComposite(errs *CompositeError) *CompositeError { for _, er := range errs.Errors { switch e := er.(type) { case *CompositeError: - if len(e.Errors) > 0 { + if e != nil && len(e.Errors) > 0 { flat := flattenComposite(e) if len(flat.Errors) > 0 { res = append(res, flat.Errors...) diff --git a/vendor/github.com/go-openapi/jsonpointer/pointer.go b/vendor/github.com/go-openapi/jsonpointer/pointer.go index 7df9853de..de60dc7dd 100644 --- a/vendor/github.com/go-openapi/jsonpointer/pointer.go +++ b/vendor/github.com/go-openapi/jsonpointer/pointer.go @@ -26,6 +26,7 @@ package jsonpointer import ( + "encoding/json" "errors" "fmt" "reflect" @@ -40,6 +41,7 @@ const ( pointerSeparator = `/` invalidStart = `JSON pointer must be empty or start with a "` + pointerSeparator + notFound = `Can't find the pointer in the document` ) var jsonPointableType = reflect.TypeOf(new(JSONPointable)).Elem() @@ -48,13 +50,13 @@ var jsonSetableType = reflect.TypeOf(new(JSONSetable)).Elem() // JSONPointable is an interface for structs to implement when they need to customize the // json pointer process type JSONPointable interface { - JSONLookup(string) (interface{}, error) + JSONLookup(string) (any, error) } // JSONSetable is an interface for structs to implement when they need to customize the // json pointer process type JSONSetable interface { - JSONSet(string, interface{}) error + JSONSet(string, any) error } // New creates a new json pointer for the given string @@ -81,9 +83,7 @@ func (p *Pointer) parse(jsonPointerString string) error { err = errors.New(invalidStart) } else { referenceTokens := strings.Split(jsonPointerString, pointerSeparator) - for _, referenceToken := range referenceTokens[1:] { - p.referenceTokens = append(p.referenceTokens, referenceToken) - } + p.referenceTokens = append(p.referenceTokens, referenceTokens[1:]...) } } @@ -91,26 +91,26 @@ func (p *Pointer) parse(jsonPointerString string) error { } // Get uses the pointer to retrieve a value from a JSON document -func (p *Pointer) Get(document interface{}) (interface{}, reflect.Kind, error) { +func (p *Pointer) Get(document any) (any, reflect.Kind, error) { return p.get(document, swag.DefaultJSONNameProvider) } // Set uses the pointer to set a value from a JSON document -func (p *Pointer) Set(document interface{}, value interface{}) (interface{}, error) { +func (p *Pointer) Set(document any, value any) (any, error) { return document, p.set(document, value, swag.DefaultJSONNameProvider) } // GetForToken gets a value for a json pointer token 1 level deep -func GetForToken(document interface{}, decodedToken string) (interface{}, reflect.Kind, error) { +func GetForToken(document any, decodedToken string) (any, reflect.Kind, error) { return getSingleImpl(document, decodedToken, swag.DefaultJSONNameProvider) } // SetForToken gets a value for a json pointer token 1 level deep -func SetForToken(document interface{}, decodedToken string, value interface{}) (interface{}, error) { +func SetForToken(document any, decodedToken string, value any) (any, error) { return document, setSingleImpl(document, value, decodedToken, swag.DefaultJSONNameProvider) } -func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) { +func getSingleImpl(node any, decodedToken string, nameProvider *swag.NameProvider) (any, reflect.Kind, error) { rValue := reflect.Indirect(reflect.ValueOf(node)) kind := rValue.Kind() @@ -159,7 +159,7 @@ func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.Nam } -func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *swag.NameProvider) error { +func setSingleImpl(node, data any, decodedToken string, nameProvider *swag.NameProvider) error { rValue := reflect.Indirect(reflect.ValueOf(node)) if ns, ok := node.(JSONSetable); ok { // pointer impl @@ -210,7 +210,7 @@ func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *sw } -func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) { +func (p *Pointer) get(node any, nameProvider *swag.NameProvider) (any, reflect.Kind, error) { if nameProvider == nil { nameProvider = swag.DefaultJSONNameProvider @@ -241,7 +241,7 @@ func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interf return node, kind, nil } -func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) error { +func (p *Pointer) set(node, data any, nameProvider *swag.NameProvider) error { knd := reflect.ValueOf(node).Kind() if knd != reflect.Ptr && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array { @@ -363,6 +363,127 @@ func (p *Pointer) String() string { return pointerString } +func (p *Pointer) Offset(document string) (int64, error) { + dec := json.NewDecoder(strings.NewReader(document)) + var offset int64 + for _, ttk := range p.DecodedTokens() { + tk, err := dec.Token() + if err != nil { + return 0, err + } + switch tk := tk.(type) { + case json.Delim: + switch tk { + case '{': + offset, err = offsetSingleObject(dec, ttk) + if err != nil { + return 0, err + } + case '[': + offset, err = offsetSingleArray(dec, ttk) + if err != nil { + return 0, err + } + default: + return 0, fmt.Errorf("invalid token %#v", tk) + } + default: + return 0, fmt.Errorf("invalid token %#v", tk) + } + } + return offset, nil +} + +func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) { + for dec.More() { + offset := dec.InputOffset() + tk, err := dec.Token() + if err != nil { + return 0, err + } + switch tk := tk.(type) { + case json.Delim: + switch tk { + case '{': + if err := drainSingle(dec); err != nil { + return 0, err + } + case '[': + if err := drainSingle(dec); err != nil { + return 0, err + } + } + case string: + if tk == decodedToken { + return offset, nil + } + default: + return 0, fmt.Errorf("invalid token %#v", tk) + } + } + return 0, fmt.Errorf("token reference %q not found", decodedToken) +} + +func offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) { + idx, err := strconv.Atoi(decodedToken) + if err != nil { + return 0, fmt.Errorf("token reference %q is not a number: %v", decodedToken, err) + } + var i int + for i = 0; i < idx && dec.More(); i++ { + tk, err := dec.Token() + if err != nil { + return 0, err + } + switch tk := tk.(type) { + case json.Delim: + switch tk { + case '{': + if err := drainSingle(dec); err != nil { + return 0, err + } + case '[': + if err := drainSingle(dec); err != nil { + return 0, err + } + } + } + } + if !dec.More() { + return 0, fmt.Errorf("token reference %q not found", decodedToken) + } + return dec.InputOffset(), nil +} + +// drainSingle drains a single level of object or array. +// The decoder has to guarantee the begining delim (i.e. '{' or '[') has been consumed. +func drainSingle(dec *json.Decoder) error { + for dec.More() { + tk, err := dec.Token() + if err != nil { + return err + } + switch tk := tk.(type) { + case json.Delim: + switch tk { + case '{': + if err := drainSingle(dec); err != nil { + return err + } + case '[': + if err := drainSingle(dec); err != nil { + return err + } + } + } + } + // Consumes the ending delim + if _, err := dec.Token(); err != nil { + return err + } + return nil +} + // Specific JSON pointer encoding here // ~0 => ~ // ~1 => / diff --git a/vendor/github.com/go-playground/validator/v10/Makefile b/vendor/github.com/go-playground/validator/v10/Makefile index ec3455bd5..09f171ba1 100644 --- a/vendor/github.com/go-playground/validator/v10/Makefile +++ b/vendor/github.com/go-playground/validator/v10/Makefile @@ -13,6 +13,6 @@ test: $(GOCMD) test -cover -race ./... bench: - $(GOCMD) test -bench=. -benchmem ./... + $(GOCMD) test -run=NONE -bench=. -benchmem ./... .PHONY: test lint linters-install \ No newline at end of file diff --git a/vendor/github.com/go-playground/validator/v10/README.md b/vendor/github.com/go-playground/validator/v10/README.md index 931b3414a..8e80d52a5 100644 --- a/vendor/github.com/go-playground/validator/v10/README.md +++ b/vendor/github.com/go-playground/validator/v10/README.md @@ -1,7 +1,7 @@ Package validator ================= -[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -![Project status](https://img.shields.io/badge/version-10.14.0-green.svg) +[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +![Project status](https://img.shields.io/badge/version-10.15.4-green.svg) [![Build Status](https://travis-ci.org/go-playground/validator.svg?branch=master)](https://travis-ci.org/go-playground/validator) [![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator) @@ -67,6 +67,12 @@ Please see https://pkg.go.dev/github.com/go-playground/validator/v10 for detaile Baked-in Validations ------ +### Special Notes: +- If new to using validator it is highly recommended to initialize it using the `WithRequiredStructEnabled` option which is opt-in to new behaviour that will become the default behaviour in v11+. See documentation for more details. +```go +validate := validator.New(validator.WithRequiredStructEnabled()) +``` + ### Fields: | Tag | Description | @@ -158,6 +164,7 @@ Baked-in Validations | credit_card | Credit Card Number | | mongodb | MongoDB ObjectID | | cron | Cron | +| spicedb | SpiceDb ObjectID/Permission/Type | | datetime | Datetime | | e164 | e164 formatted phone number | | email | E-mail String @@ -259,71 +266,72 @@ Benchmarks ------ ###### Run on MacBook Pro (15-inch, 2017) go version go1.10.2 darwin/amd64 ```go +go version go1.21.0 darwin/arm64 goos: darwin -goarch: amd64 -pkg: github.com/go-playground/validator -BenchmarkFieldSuccess-8 20000000 83.6 ns/op 0 B/op 0 allocs/op -BenchmarkFieldSuccessParallel-8 50000000 26.8 ns/op 0 B/op 0 allocs/op -BenchmarkFieldFailure-8 5000000 291 ns/op 208 B/op 4 allocs/op -BenchmarkFieldFailureParallel-8 20000000 107 ns/op 208 B/op 4 allocs/op -BenchmarkFieldArrayDiveSuccess-8 2000000 623 ns/op 201 B/op 11 allocs/op -BenchmarkFieldArrayDiveSuccessParallel-8 10000000 237 ns/op 201 B/op 11 allocs/op -BenchmarkFieldArrayDiveFailure-8 2000000 859 ns/op 412 B/op 16 allocs/op -BenchmarkFieldArrayDiveFailureParallel-8 5000000 335 ns/op 413 B/op 16 allocs/op -BenchmarkFieldMapDiveSuccess-8 1000000 1292 ns/op 432 B/op 18 allocs/op -BenchmarkFieldMapDiveSuccessParallel-8 3000000 467 ns/op 432 B/op 18 allocs/op -BenchmarkFieldMapDiveFailure-8 1000000 1082 ns/op 512 B/op 16 allocs/op -BenchmarkFieldMapDiveFailureParallel-8 5000000 425 ns/op 512 B/op 16 allocs/op -BenchmarkFieldMapDiveWithKeysSuccess-8 1000000 1539 ns/op 480 B/op 21 allocs/op -BenchmarkFieldMapDiveWithKeysSuccessParallel-8 3000000 613 ns/op 480 B/op 21 allocs/op -BenchmarkFieldMapDiveWithKeysFailure-8 1000000 1413 ns/op 721 B/op 21 allocs/op -BenchmarkFieldMapDiveWithKeysFailureParallel-8 3000000 575 ns/op 721 B/op 21 allocs/op -BenchmarkFieldCustomTypeSuccess-8 10000000 216 ns/op 32 B/op 2 allocs/op -BenchmarkFieldCustomTypeSuccessParallel-8 20000000 82.2 ns/op 32 B/op 2 allocs/op -BenchmarkFieldCustomTypeFailure-8 5000000 274 ns/op 208 B/op 4 allocs/op -BenchmarkFieldCustomTypeFailureParallel-8 20000000 116 ns/op 208 B/op 4 allocs/op -BenchmarkFieldOrTagSuccess-8 2000000 740 ns/op 16 B/op 1 allocs/op -BenchmarkFieldOrTagSuccessParallel-8 3000000 474 ns/op 16 B/op 1 allocs/op -BenchmarkFieldOrTagFailure-8 3000000 471 ns/op 224 B/op 5 allocs/op -BenchmarkFieldOrTagFailureParallel-8 3000000 414 ns/op 224 B/op 5 allocs/op -BenchmarkStructLevelValidationSuccess-8 10000000 213 ns/op 32 B/op 2 allocs/op -BenchmarkStructLevelValidationSuccessParallel-8 20000000 91.8 ns/op 32 B/op 2 allocs/op -BenchmarkStructLevelValidationFailure-8 3000000 473 ns/op 304 B/op 8 allocs/op -BenchmarkStructLevelValidationFailureParallel-8 10000000 234 ns/op 304 B/op 8 allocs/op -BenchmarkStructSimpleCustomTypeSuccess-8 5000000 385 ns/op 32 B/op 2 allocs/op -BenchmarkStructSimpleCustomTypeSuccessParallel-8 10000000 161 ns/op 32 B/op 2 allocs/op -BenchmarkStructSimpleCustomTypeFailure-8 2000000 640 ns/op 424 B/op 9 allocs/op -BenchmarkStructSimpleCustomTypeFailureParallel-8 5000000 318 ns/op 440 B/op 10 allocs/op -BenchmarkStructFilteredSuccess-8 2000000 597 ns/op 288 B/op 9 allocs/op -BenchmarkStructFilteredSuccessParallel-8 10000000 266 ns/op 288 B/op 9 allocs/op -BenchmarkStructFilteredFailure-8 3000000 454 ns/op 256 B/op 7 allocs/op -BenchmarkStructFilteredFailureParallel-8 10000000 214 ns/op 256 B/op 7 allocs/op -BenchmarkStructPartialSuccess-8 3000000 502 ns/op 256 B/op 6 allocs/op -BenchmarkStructPartialSuccessParallel-8 10000000 225 ns/op 256 B/op 6 allocs/op -BenchmarkStructPartialFailure-8 2000000 702 ns/op 480 B/op 11 allocs/op -BenchmarkStructPartialFailureParallel-8 5000000 329 ns/op 480 B/op 11 allocs/op -BenchmarkStructExceptSuccess-8 2000000 793 ns/op 496 B/op 12 allocs/op -BenchmarkStructExceptSuccessParallel-8 10000000 193 ns/op 240 B/op 5 allocs/op -BenchmarkStructExceptFailure-8 2000000 639 ns/op 464 B/op 10 allocs/op -BenchmarkStructExceptFailureParallel-8 5000000 300 ns/op 464 B/op 10 allocs/op -BenchmarkStructSimpleCrossFieldSuccess-8 3000000 417 ns/op 72 B/op 3 allocs/op -BenchmarkStructSimpleCrossFieldSuccessParallel-8 10000000 163 ns/op 72 B/op 3 allocs/op -BenchmarkStructSimpleCrossFieldFailure-8 2000000 645 ns/op 304 B/op 8 allocs/op -BenchmarkStructSimpleCrossFieldFailureParallel-8 5000000 285 ns/op 304 B/op 8 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 3000000 588 ns/op 80 B/op 4 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 10000000 221 ns/op 80 B/op 4 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2000000 868 ns/op 320 B/op 9 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 5000000 337 ns/op 320 B/op 9 allocs/op -BenchmarkStructSimpleSuccess-8 5000000 260 ns/op 0 B/op 0 allocs/op -BenchmarkStructSimpleSuccessParallel-8 20000000 90.6 ns/op 0 B/op 0 allocs/op -BenchmarkStructSimpleFailure-8 2000000 619 ns/op 424 B/op 9 allocs/op -BenchmarkStructSimpleFailureParallel-8 5000000 296 ns/op 424 B/op 9 allocs/op -BenchmarkStructComplexSuccess-8 1000000 1454 ns/op 128 B/op 8 allocs/op -BenchmarkStructComplexSuccessParallel-8 3000000 579 ns/op 128 B/op 8 allocs/op -BenchmarkStructComplexFailure-8 300000 4140 ns/op 3041 B/op 53 allocs/op -BenchmarkStructComplexFailureParallel-8 1000000 2127 ns/op 3041 B/op 53 allocs/op -BenchmarkOneof-8 10000000 140 ns/op 0 B/op 0 allocs/op -BenchmarkOneofParallel-8 20000000 70.1 ns/op 0 B/op 0 allocs/op +goarch: arm64 +pkg: github.com/go-playground/validator/v10 +BenchmarkFieldSuccess-8 33142266 35.94 ns/op 0 B/op 0 allocs/op +BenchmarkFieldSuccessParallel-8 200816191 6.568 ns/op 0 B/op 0 allocs/op +BenchmarkFieldFailure-8 6779707 175.1 ns/op 200 B/op 4 allocs/op +BenchmarkFieldFailureParallel-8 11044147 108.4 ns/op 200 B/op 4 allocs/op +BenchmarkFieldArrayDiveSuccess-8 6054232 194.4 ns/op 97 B/op 5 allocs/op +BenchmarkFieldArrayDiveSuccessParallel-8 12523388 94.07 ns/op 97 B/op 5 allocs/op +BenchmarkFieldArrayDiveFailure-8 3587043 334.3 ns/op 300 B/op 10 allocs/op +BenchmarkFieldArrayDiveFailureParallel-8 5816665 200.8 ns/op 300 B/op 10 allocs/op +BenchmarkFieldMapDiveSuccess-8 2217910 540.1 ns/op 288 B/op 14 allocs/op +BenchmarkFieldMapDiveSuccessParallel-8 4446698 258.7 ns/op 288 B/op 14 allocs/op +BenchmarkFieldMapDiveFailure-8 2392759 504.6 ns/op 376 B/op 13 allocs/op +BenchmarkFieldMapDiveFailureParallel-8 4244199 286.9 ns/op 376 B/op 13 allocs/op +BenchmarkFieldMapDiveWithKeysSuccess-8 2005857 592.1 ns/op 288 B/op 14 allocs/op +BenchmarkFieldMapDiveWithKeysSuccessParallel-8 4400850 296.9 ns/op 288 B/op 14 allocs/op +BenchmarkFieldMapDiveWithKeysFailure-8 1850227 643.8 ns/op 553 B/op 16 allocs/op +BenchmarkFieldMapDiveWithKeysFailureParallel-8 3293233 375.1 ns/op 553 B/op 16 allocs/op +BenchmarkFieldCustomTypeSuccess-8 12174412 98.25 ns/op 32 B/op 2 allocs/op +BenchmarkFieldCustomTypeSuccessParallel-8 34389907 35.49 ns/op 32 B/op 2 allocs/op +BenchmarkFieldCustomTypeFailure-8 7582524 156.6 ns/op 184 B/op 3 allocs/op +BenchmarkFieldCustomTypeFailureParallel-8 13019902 92.79 ns/op 184 B/op 3 allocs/op +BenchmarkFieldOrTagSuccess-8 3427260 349.4 ns/op 16 B/op 1 allocs/op +BenchmarkFieldOrTagSuccessParallel-8 15144128 81.25 ns/op 16 B/op 1 allocs/op +BenchmarkFieldOrTagFailure-8 5913546 201.9 ns/op 216 B/op 5 allocs/op +BenchmarkFieldOrTagFailureParallel-8 9810212 113.7 ns/op 216 B/op 5 allocs/op +BenchmarkStructLevelValidationSuccess-8 13456327 87.66 ns/op 16 B/op 1 allocs/op +BenchmarkStructLevelValidationSuccessParallel-8 41818888 27.77 ns/op 16 B/op 1 allocs/op +BenchmarkStructLevelValidationFailure-8 4166284 272.6 ns/op 264 B/op 7 allocs/op +BenchmarkStructLevelValidationFailureParallel-8 7594581 152.1 ns/op 264 B/op 7 allocs/op +BenchmarkStructSimpleCustomTypeSuccess-8 6508082 182.6 ns/op 32 B/op 2 allocs/op +BenchmarkStructSimpleCustomTypeSuccessParallel-8 23078605 54.78 ns/op 32 B/op 2 allocs/op +BenchmarkStructSimpleCustomTypeFailure-8 3118352 381.0 ns/op 416 B/op 9 allocs/op +BenchmarkStructSimpleCustomTypeFailureParallel-8 5300738 224.1 ns/op 432 B/op 10 allocs/op +BenchmarkStructFilteredSuccess-8 4761807 251.1 ns/op 216 B/op 5 allocs/op +BenchmarkStructFilteredSuccessParallel-8 8792598 128.6 ns/op 216 B/op 5 allocs/op +BenchmarkStructFilteredFailure-8 5202573 232.1 ns/op 216 B/op 5 allocs/op +BenchmarkStructFilteredFailureParallel-8 9591267 121.4 ns/op 216 B/op 5 allocs/op +BenchmarkStructPartialSuccess-8 5188512 231.6 ns/op 224 B/op 4 allocs/op +BenchmarkStructPartialSuccessParallel-8 9179776 123.1 ns/op 224 B/op 4 allocs/op +BenchmarkStructPartialFailure-8 3071212 392.5 ns/op 440 B/op 9 allocs/op +BenchmarkStructPartialFailureParallel-8 5344261 223.7 ns/op 440 B/op 9 allocs/op +BenchmarkStructExceptSuccess-8 3184230 375.0 ns/op 424 B/op 8 allocs/op +BenchmarkStructExceptSuccessParallel-8 10090130 108.9 ns/op 208 B/op 3 allocs/op +BenchmarkStructExceptFailure-8 3347226 357.7 ns/op 424 B/op 8 allocs/op +BenchmarkStructExceptFailureParallel-8 5654923 209.5 ns/op 424 B/op 8 allocs/op +BenchmarkStructSimpleCrossFieldSuccess-8 5232265 229.1 ns/op 56 B/op 3 allocs/op +BenchmarkStructSimpleCrossFieldSuccessParallel-8 17436674 64.75 ns/op 56 B/op 3 allocs/op +BenchmarkStructSimpleCrossFieldFailure-8 3128613 383.6 ns/op 272 B/op 8 allocs/op +BenchmarkStructSimpleCrossFieldFailureParallel-8 6994113 168.8 ns/op 272 B/op 8 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 3506487 340.9 ns/op 64 B/op 4 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 13431300 91.77 ns/op 64 B/op 4 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2410566 500.9 ns/op 288 B/op 9 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 6344510 188.2 ns/op 288 B/op 9 allocs/op +BenchmarkStructSimpleSuccess-8 8922726 133.8 ns/op 0 B/op 0 allocs/op +BenchmarkStructSimpleSuccessParallel-8 55291153 23.63 ns/op 0 B/op 0 allocs/op +BenchmarkStructSimpleFailure-8 3171553 378.4 ns/op 416 B/op 9 allocs/op +BenchmarkStructSimpleFailureParallel-8 5571692 212.0 ns/op 416 B/op 9 allocs/op +BenchmarkStructComplexSuccess-8 1683750 714.5 ns/op 224 B/op 5 allocs/op +BenchmarkStructComplexSuccessParallel-8 4578046 257.0 ns/op 224 B/op 5 allocs/op +BenchmarkStructComplexFailure-8 481585 2547 ns/op 3041 B/op 48 allocs/op +BenchmarkStructComplexFailureParallel-8 965764 1577 ns/op 3040 B/op 48 allocs/op +BenchmarkOneof-8 17380881 68.50 ns/op 0 B/op 0 allocs/op +BenchmarkOneofParallel-8 8084733 153.5 ns/op 0 B/op 0 allocs/op ``` Complementary Software diff --git a/vendor/github.com/go-playground/validator/v10/baked_in.go b/vendor/github.com/go-playground/validator/v10/baked_in.go index 8e6b169cb..0b6233070 100644 --- a/vendor/github.com/go-playground/validator/v10/baked_in.go +++ b/vendor/github.com/go-playground/validator/v10/baked_in.go @@ -23,7 +23,7 @@ import ( "golang.org/x/text/language" "github.com/gabriel-vasile/mimetype" - "github.com/leodido/go-urn" + urn "github.com/leodido/go-urn" ) // Func accepts a FieldLevel interface for all validation needs. The return @@ -230,6 +230,7 @@ var ( "luhn_checksum": hasLuhnChecksum, "mongodb": isMongoDB, "cron": isCron, + "spicedb": isSpiceDB, } ) @@ -372,9 +373,9 @@ func isMAC(fl FieldLevel) bool { // isCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address. func isCIDRv4(fl FieldLevel) bool { - ip, _, err := net.ParseCIDR(fl.Field().String()) + ip, net, err := net.ParseCIDR(fl.Field().String()) - return err == nil && ip.To4() != nil + return err == nil && ip.To4() != nil && net.IP.Equal(ip) } // isCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address. @@ -1294,8 +1295,13 @@ func isEq(fl FieldLevel) bool { return field.Uint() == p - case reflect.Float32, reflect.Float64: - p := asFloat(param) + case reflect.Float32: + p := asFloat32(param) + + return field.Float() == p + + case reflect.Float64: + p := asFloat64(param) return field.Float() == p @@ -1414,25 +1420,21 @@ func isURL(fl FieldLevel) bool { switch field.Kind() { case reflect.String: - var i int s := field.String() - // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195 - // emulate browser and strip the '#' suffix prior to validation. see issue-#237 - if i = strings.Index(s, "#"); i > -1 { - s = s[:i] - } - if len(s) == 0 { return false } - url, err := url.ParseRequestURI(s) - + url, err := url.Parse(s) if err != nil || url.Scheme == "" { return false } + if url.Host == "" && url.Fragment == "" && url.Opaque == "" { + return false + } + return true } @@ -1450,7 +1452,13 @@ func isHttpURL(fl FieldLevel) bool { case reflect.String: s := strings.ToLower(field.String()) - return strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://") + + url, err := url.Parse(s) + if err != nil || url.Host == "" { + return false + } + + return url.Scheme == "http" || url.Scheme == "https" } panic(fmt.Sprintf("Bad field type %T", field.Interface())) @@ -1559,6 +1567,10 @@ func isFilePath(fl FieldLevel) bool { field := fl.Field() + // Not valid if it is a directory. + if isDir(fl) { + return false + } // If it exists, it obviously is valid. // This is done first to avoid code duplication and unnecessary additional logic. if exists = isFile(fl); exists { @@ -1708,7 +1720,7 @@ func hasValue(fl FieldLevel) bool { if fl.(*validate).fldIsPointer && field.Interface() != nil { return true } - return field.IsValid() && field.Interface() != reflect.Zero(field.Type()).Interface() + return field.IsValid() && !field.IsZero() } } @@ -1732,7 +1744,7 @@ func requireCheckFieldKind(fl FieldLevel, param string, defaultNotFoundValue boo if nullable && field.Interface() != nil { return false } - return field.IsValid() && field.Interface() == reflect.Zero(field.Type()).Interface() + return field.IsValid() && field.IsZero() } } @@ -1753,8 +1765,11 @@ func requireCheckFieldValue( case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return field.Uint() == asUint(value) - case reflect.Float32, reflect.Float64: - return field.Float() == asFloat(value) + case reflect.Float32: + return field.Float() == asFloat32(value) + + case reflect.Float64: + return field.Float() == asFloat64(value) case reflect.Slice, reflect.Map, reflect.Array: return int64(field.Len()) == asInt(value) @@ -2053,8 +2068,13 @@ func isGte(fl FieldLevel) bool { return field.Uint() >= p - case reflect.Float32, reflect.Float64: - p := asFloat(param) + case reflect.Float32: + p := asFloat32(param) + + return field.Float() >= p + + case reflect.Float64: + p := asFloat64(param) return field.Float() >= p @@ -2099,10 +2119,16 @@ func isGt(fl FieldLevel) bool { return field.Uint() > p - case reflect.Float32, reflect.Float64: - p := asFloat(param) + case reflect.Float32: + p := asFloat32(param) + + return field.Float() > p + + case reflect.Float64: + p := asFloat64(param) return field.Float() > p + case reflect.Struct: if field.Type().ConvertibleTo(timeType) { @@ -2141,8 +2167,13 @@ func hasLengthOf(fl FieldLevel) bool { return field.Uint() == p - case reflect.Float32, reflect.Float64: - p := asFloat(param) + case reflect.Float32: + p := asFloat32(param) + + return field.Float() == p + + case reflect.Float64: + p := asFloat64(param) return field.Float() == p } @@ -2274,8 +2305,13 @@ func isLte(fl FieldLevel) bool { return field.Uint() <= p - case reflect.Float32, reflect.Float64: - p := asFloat(param) + case reflect.Float32: + p := asFloat32(param) + + return field.Float() <= p + + case reflect.Float64: + p := asFloat64(param) return field.Float() <= p @@ -2320,8 +2356,13 @@ func isLt(fl FieldLevel) bool { return field.Uint() < p - case reflect.Float32, reflect.Float64: - p := asFloat(param) + case reflect.Float32: + p := asFloat32(param) + + return field.Float() < p + + case reflect.Float64: + p := asFloat64(param) return field.Float() < p @@ -2568,9 +2609,17 @@ func isDirPath(fl FieldLevel) bool { func isJSON(fl FieldLevel) bool { field := fl.Field() - if field.Kind() == reflect.String { + switch field.Kind() { + case reflect.String: val := field.String() return json.Valid([]byte(val)) + case reflect.Slice: + fieldType := field.Type() + + if fieldType.ConvertibleTo(byteSliceType) { + b := field.Convert(byteSliceType).Interface().([]byte) + return json.Valid(b) + } } panic(fmt.Sprintf("Bad field type %T", field.Interface())) @@ -2798,6 +2847,23 @@ func isMongoDB(fl FieldLevel) bool { return mongodbRegex.MatchString(val) } +// isSpiceDB is the validation function for validating if the current field's value is valid for use with Authzed SpiceDB in the indicated way +func isSpiceDB(fl FieldLevel) bool { + val := fl.Field().String() + param := fl.Param() + + switch param { + case "permission": + return spicedbPermissionRegex.MatchString(val) + case "type": + return spicedbTypeRegex.MatchString(val) + case "id", "": + return spicedbIDRegex.MatchString(val) + } + + panic("Unrecognized parameter: " + param) +} + // isCreditCard is the validation function for validating if the current field's value is a valid credit card number func isCreditCard(fl FieldLevel) bool { val := fl.Field().String() diff --git a/vendor/github.com/go-playground/validator/v10/doc.go b/vendor/github.com/go-playground/validator/v10/doc.go index f5aa9e523..c4dbb595f 100644 --- a/vendor/github.com/go-playground/validator/v10/doc.go +++ b/vendor/github.com/go-playground/validator/v10/doc.go @@ -247,7 +247,7 @@ Example #2 This validates that the value is not the data types default zero value. For numbers ensures value is not zero. For strings ensures value is not "". For slices, maps, pointers, interfaces, channels and functions -ensures the value is not nil. +ensures the value is not nil. For structs ensures value is not the zero value when using WithRequiredStructEnabled. Usage: required @@ -256,7 +256,7 @@ ensures the value is not nil. The field under validation must be present and not empty only if all the other specified fields are equal to the value following the specified field. For strings ensures value is not "". For slices, maps, pointers, -interfaces, channels and functions ensures the value is not nil. +interfaces, channels and functions ensures the value is not nil. For structs ensures value is not the zero value. Usage: required_if @@ -273,7 +273,7 @@ Examples: The field under validation must be present and not empty unless all the other specified fields are equal to the value following the specified field. For strings ensures value is not "". For slices, maps, pointers, -interfaces, channels and functions ensures the value is not nil. +interfaces, channels and functions ensures the value is not nil. For structs ensures value is not the zero value. Usage: required_unless @@ -290,7 +290,7 @@ Examples: The field under validation must be present and not empty only if any of the other specified fields are present. For strings ensures value is not "". For slices, maps, pointers, interfaces, channels and functions -ensures the value is not nil. +ensures the value is not nil. For structs ensures value is not the zero value. Usage: required_with @@ -307,7 +307,7 @@ Examples: The field under validation must be present and not empty only if all of the other specified fields are present. For strings ensures value is not "". For slices, maps, pointers, interfaces, channels and functions -ensures the value is not nil. +ensures the value is not nil. For structs ensures value is not the zero value. Usage: required_with_all @@ -321,7 +321,7 @@ Example: The field under validation must be present and not empty only when any of the other specified fields are not present. For strings ensures value is not "". For slices, maps, pointers, interfaces, channels and functions -ensures the value is not nil. +ensures the value is not nil. For structs ensures value is not the zero value. Usage: required_without @@ -338,7 +338,7 @@ Examples: The field under validation must be present and not empty only when all of the other specified fields are not present. For strings ensures value is not "". For slices, maps, pointers, interfaces, channels and functions -ensures the value is not nil. +ensures the value is not nil. For structs ensures value is not the zero value. Usage: required_without_all @@ -352,7 +352,7 @@ Example: The field under validation must not be present or not empty only if all the other specified fields are equal to the value following the specified field. For strings ensures value is not "". For slices, maps, pointers, -interfaces, channels and functions ensures the value is not nil. +interfaces, channels and functions ensures the value is not nil. For structs ensures value is not the zero value. Usage: excluded_if @@ -369,7 +369,7 @@ Examples: The field under validation must not be present or empty unless all the other specified fields are equal to the value following the specified field. For strings ensures value is not "". For slices, maps, pointers, -interfaces, channels and functions ensures the value is not nil. +interfaces, channels and functions ensures the value is not nil. For structs ensures value is not the zero value. Usage: excluded_unless @@ -879,8 +879,6 @@ This is done using os.Stat and github.com/gabriel-vasile/mimetype Usage: image -# URL String - # File Path This validates that a string value contains a valid file path but does not @@ -1384,6 +1382,12 @@ This validates that a string value contains a valid cron expression. Usage: cron +# SpiceDb ObjectID/Permission/Object Type + +This validates that a string is valid for use with SpiceDb for the indicated purpose. If no purpose is given, a purpose of 'id' is assumed. + + Usage: spicedb=id|permission|type + # Alias Validators and Tags Alias Validators and Tags diff --git a/vendor/github.com/go-playground/validator/v10/options.go b/vendor/github.com/go-playground/validator/v10/options.go new file mode 100644 index 000000000..1dea56fd7 --- /dev/null +++ b/vendor/github.com/go-playground/validator/v10/options.go @@ -0,0 +1,16 @@ +package validator + +// Option represents a configurations option to be applied to validator during initialization. +type Option func(*Validate) + +// WithRequiredStructEnabled enables required tag on non-pointer structs to be applied instead of ignored. +// +// This was made opt-in behaviour in order to maintain backward compatibility with the behaviour previous +// to being able to apply struct level validations on struct fields directly. +// +// It is recommended you enabled this as it will be the default behaviour in v11+ +func WithRequiredStructEnabled() Option { + return func(v *Validate) { + v.requiredStructEnabled = true + } +} diff --git a/vendor/github.com/go-playground/validator/v10/regexes.go b/vendor/github.com/go-playground/validator/v10/regexes.go index ba450b3d0..6c8f98560 100644 --- a/vendor/github.com/go-playground/validator/v10/regexes.go +++ b/vendor/github.com/go-playground/validator/v10/regexes.go @@ -68,6 +68,9 @@ const ( cveRegexString = `^CVE-(1999|2\d{3})-(0[^0]\d{2}|0\d[^0]\d{1}|0\d{2}[^0]|[1-9]{1}\d{3,})$` // CVE Format Id https://cve.mitre.org/cve/identifiers/syntaxchange.html mongodbRegexString = "^[a-f\\d]{24}$" cronRegexString = `(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)|((((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*) ?){5,7})` + spicedbIDRegexString = `^(([a-zA-Z0-9/_|\-=+]{1,})|\*)$` + spicedbPermissionRegexString = "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + spicedbTypeRegexString = "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)?[a-z][a-z0-9_]{1,62}[a-z0-9]$" ) var ( @@ -134,4 +137,7 @@ var ( cveRegex = regexp.MustCompile(cveRegexString) mongodbRegex = regexp.MustCompile(mongodbRegexString) cronRegex = regexp.MustCompile(cronRegexString) + spicedbIDRegex = regexp.MustCompile(spicedbIDRegexString) + spicedbPermissionRegex = regexp.MustCompile(spicedbPermissionRegexString) + spicedbTypeRegex = regexp.MustCompile(spicedbTypeRegexString) ) diff --git a/vendor/github.com/go-playground/validator/v10/util.go b/vendor/github.com/go-playground/validator/v10/util.go index 3925cfe1c..4bd947bdf 100644 --- a/vendor/github.com/go-playground/validator/v10/util.go +++ b/vendor/github.com/go-playground/validator/v10/util.go @@ -261,13 +261,19 @@ func asUint(param string) uint64 { return i } -// asFloat returns the parameter as a float64 +// asFloat64 returns the parameter as a float64 // or panics if it can't convert -func asFloat(param string) float64 { - +func asFloat64(param string) float64 { i, err := strconv.ParseFloat(param, 64) panicIf(err) + return i +} +// asFloat64 returns the parameter as a float64 +// or panics if it can't convert +func asFloat32(param string) float64 { + i, err := strconv.ParseFloat(param, 32) + panicIf(err) return i } diff --git a/vendor/github.com/go-playground/validator/v10/validator.go b/vendor/github.com/go-playground/validator/v10/validator.go index 6f6d53ada..342c4ec24 100644 --- a/vendor/github.com/go-playground/validator/v10/validator.go +++ b/vendor/github.com/go-playground/validator/v10/validator.go @@ -99,6 +99,8 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr current, kind, v.fldIsPointer = v.extractTypeInternal(current, false) + var isNestedStruct bool + switch kind { case reflect.Ptr, reflect.Interface, reflect.Invalid: @@ -160,86 +162,61 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr } } - case reflect.Struct: - - typ = current.Type() - - if !typ.ConvertibleTo(timeType) { - - if ct != nil { - - if ct.typeof == typeStructOnly { - goto CONTINUE - } else if ct.typeof == typeIsDefault { - // set Field Level fields - v.slflParent = parent - v.flField = current - v.cf = cf - v.ct = ct - - if !ct.fn(ctx, v) { - v.str1 = string(append(ns, cf.altName...)) - - if v.v.hasTagNameFunc { - v.str2 = string(append(structNs, cf.name...)) - } else { - v.str2 = v.str1 - } - - v.errs = append(v.errs, - &fieldError{ - v: v.v, - tag: ct.aliasTag, - actualTag: ct.tag, - ns: v.str1, - structNs: v.str2, - fieldLen: uint8(len(cf.altName)), - structfieldLen: uint8(len(cf.name)), - value: current.Interface(), - param: ct.param, - kind: kind, - typ: typ, - }, - ) - return - } - } - - ct = ct.next - } - - if ct != nil && ct.typeof == typeNoStructLevel { - return - } - - CONTINUE: - // if len == 0 then validating using 'Var' or 'VarWithValue' - // Var - doesn't make much sense to do it that way, should call 'Struct', but no harm... - // VarWithField - this allows for validating against each field within the struct against a specific value - // pretty handy in certain situations - if len(cf.name) > 0 { - ns = append(append(ns, cf.altName...), '.') - structNs = append(append(structNs, cf.name...), '.') - } - - v.validateStruct(ctx, parent, current, typ, ns, structNs, ct) + if kind == reflect.Invalid { return } - } - if ct == nil || !ct.hasTag { - return + case reflect.Struct: + isNestedStruct = !current.Type().ConvertibleTo(timeType) + // For backward compatibility before struct level validation tags were supported + // as there were a number of projects relying on `required` not failing on non-pointer + // structs. Since it's basically nonsensical to use `required` with a non-pointer struct + // are explicitly skipping the required validation for it. This WILL be removed in the + // next major version. + if isNestedStruct && !v.v.requiredStructEnabled && ct != nil && ct.tag == requiredTag { + ct = ct.next + } } typ = current.Type() OUTER: for { - if ct == nil { + if ct == nil || !ct.hasTag || (isNestedStruct && len(cf.name) == 0) { + // isNestedStruct check here + if isNestedStruct { + // if len == 0 then validating using 'Var' or 'VarWithValue' + // Var - doesn't make much sense to do it that way, should call 'Struct', but no harm... + // VarWithField - this allows for validating against each field within the struct against a specific value + // pretty handy in certain situations + if len(cf.name) > 0 { + ns = append(append(ns, cf.altName...), '.') + structNs = append(append(structNs, cf.name...), '.') + } + + v.validateStruct(ctx, parent, current, typ, ns, structNs, ct) + } return } switch ct.typeof { + case typeNoStructLevel: + return + + case typeStructOnly: + if isNestedStruct { + // if len == 0 then validating using 'Var' or 'VarWithValue' + // Var - doesn't make much sense to do it that way, should call 'Struct', but no harm... + // VarWithField - this allows for validating against each field within the struct against a specific value + // pretty handy in certain situations + if len(cf.name) > 0 { + ns = append(append(ns, cf.altName...), '.') + structNs = append(append(structNs, cf.name...), '.') + } + + v.validateStruct(ctx, parent, current, typ, ns, structNs, ct) + } + return case typeOmitEmpty: @@ -366,7 +343,7 @@ OUTER: ct = ct.next if ct == nil { - return + continue OUTER } if ct.typeof != typeOr { diff --git a/vendor/github.com/go-playground/validator/v10/validator_instance.go b/vendor/github.com/go-playground/validator/v10/validator_instance.go index d2ee8fe38..a4dbdd098 100644 --- a/vendor/github.com/go-playground/validator/v10/validator_instance.go +++ b/vendor/github.com/go-playground/validator/v10/validator_instance.go @@ -53,6 +53,8 @@ var ( timeDurationType = reflect.TypeOf(time.Duration(0)) timeType = reflect.TypeOf(time.Time{}) + byteSliceType = reflect.TypeOf([]byte{}) + defaultCField = &cField{namesEqual: true} ) @@ -77,19 +79,20 @@ type internalValidationFuncWrapper struct { // Validate contains the validator settings and cache type Validate struct { - tagName string - pool *sync.Pool - hasCustomFuncs bool - hasTagNameFunc bool - tagNameFunc TagNameFunc - structLevelFuncs map[reflect.Type]StructLevelFuncCtx - customFuncs map[reflect.Type]CustomTypeFunc - aliases map[string]string - validations map[string]internalValidationFuncWrapper - transTagFunc map[ut.Translator]map[string]TranslationFunc // map[]map[]TranslationFunc - rules map[reflect.Type]map[string]string - tagCache *tagCache - structCache *structCache + tagName string + pool *sync.Pool + tagNameFunc TagNameFunc + structLevelFuncs map[reflect.Type]StructLevelFuncCtx + customFuncs map[reflect.Type]CustomTypeFunc + aliases map[string]string + validations map[string]internalValidationFuncWrapper + transTagFunc map[ut.Translator]map[string]TranslationFunc // map[]map[]TranslationFunc + rules map[reflect.Type]map[string]string + tagCache *tagCache + structCache *structCache + hasCustomFuncs bool + hasTagNameFunc bool + requiredStructEnabled bool } // New returns a new instance of 'validate' with sane defaults. @@ -97,7 +100,7 @@ type Validate struct { // It caches information about your struct and validations, // in essence only parsing your validation tags once per struct type. // Using multiple instances neglects the benefit of caching. -func New() *Validate { +func New(options ...Option) *Validate { tc := new(tagCache) tc.m.Store(make(map[string]*cTag)) @@ -144,6 +147,9 @@ func New() *Validate { }, } + for _, o := range options { + o(v) + } return v } diff --git a/vendor/github.com/goccy/go-json/.codecov.yml b/vendor/github.com/goccy/go-json/.codecov.yml new file mode 100644 index 000000000..e98134570 --- /dev/null +++ b/vendor/github.com/goccy/go-json/.codecov.yml @@ -0,0 +1,32 @@ +codecov: + require_ci_to_pass: yes + +coverage: + precision: 2 + round: down + range: "70...100" + + status: + project: + default: + target: 70% + threshold: 2% + patch: off + changes: no + +parsers: + gcov: + branch_detection: + conditional: yes + loop: yes + method: no + macro: no + +comment: + layout: "header,diff" + behavior: default + require_changes: no + +ignore: + - internal/encoder/vm_color + - internal/encoder/vm_color_indent diff --git a/vendor/github.com/goccy/go-json/.gitignore b/vendor/github.com/goccy/go-json/.gitignore new file mode 100644 index 000000000..378283829 --- /dev/null +++ b/vendor/github.com/goccy/go-json/.gitignore @@ -0,0 +1,2 @@ +cover.html +cover.out diff --git a/vendor/github.com/goccy/go-json/.golangci.yml b/vendor/github.com/goccy/go-json/.golangci.yml new file mode 100644 index 000000000..57ae5a528 --- /dev/null +++ b/vendor/github.com/goccy/go-json/.golangci.yml @@ -0,0 +1,83 @@ +run: + skip-files: + - encode_optype.go + - ".*_test\\.go$" + +linters-settings: + govet: + enable-all: true + disable: + - shadow + +linters: + enable-all: true + disable: + - dogsled + - dupl + - exhaustive + - exhaustivestruct + - errorlint + - forbidigo + - funlen + - gci + - gochecknoglobals + - gochecknoinits + - gocognit + - gocritic + - gocyclo + - godot + - godox + - goerr113 + - gofumpt + - gomnd + - gosec + - ifshort + - lll + - makezero + - nakedret + - nestif + - nlreturn + - paralleltest + - testpackage + - thelper + - wrapcheck + - interfacer + - lll + - nakedret + - nestif + - nlreturn + - testpackage + - wsl + - varnamelen + - nilnil + - ireturn + - govet + - forcetypeassert + - cyclop + - containedctx + - revive + +issues: + exclude-rules: + # not needed + - path: /*.go + text: "ST1003: should not use underscores in package names" + linters: + - stylecheck + - path: /*.go + text: "don't use an underscore in package name" + linters: + - golint + - path: rtype.go + linters: + - golint + - stylecheck + - path: error.go + linters: + - staticcheck + + # Maximum issues count per one linter. Set to 0 to disable. Default is 50. + max-issues-per-linter: 0 + + # Maximum count of issues with the same text. Set to 0 to disable. Default is 3. + max-same-issues: 0 diff --git a/vendor/github.com/goccy/go-json/CHANGELOG.md b/vendor/github.com/goccy/go-json/CHANGELOG.md new file mode 100644 index 000000000..d09bb89c3 --- /dev/null +++ b/vendor/github.com/goccy/go-json/CHANGELOG.md @@ -0,0 +1,425 @@ +# v0.10.2 - 2023/03/20 + +### New features + +* Support DebugDOT option for debugging encoder ( #440 ) + +### Fix bugs + +* Fix combination of embedding structure and omitempty option ( #442 ) + +# v0.10.1 - 2023/03/13 + +### Fix bugs + +* Fix checkptr error for array decoder ( #415 ) +* Fix added buffer size check when decoding key ( #430 ) +* Fix handling of anonymous fields other than struct ( #431 ) +* Fix to not optimize when lower conversion can't handle byte-by-byte ( #432 ) +* Fix a problem that MarshalIndent does not work when UnorderedMap is specified ( #435 ) +* Fix mapDecoder.DecodeStream() for empty objects containing whitespace ( #425 ) +* Fix an issue that could not set the correct NextField for fields in the embedded structure ( #438 ) + +# v0.10.0 - 2022/11/29 + +### New features + +* Support JSON Path ( #250 ) + +### Fix bugs + +* Fix marshaler for map's key ( #409 ) + +# v0.9.11 - 2022/08/18 + +### Fix bugs + +* Fix unexpected behavior when buffer ends with backslash ( #383 ) +* Fix stream decoding of escaped character ( #387 ) + +# v0.9.10 - 2022/07/15 + +### Fix bugs + +* Fix boundary exception of type caching ( #382 ) + +# v0.9.9 - 2022/07/15 + +### Fix bugs + +* Fix encoding of directed interface with typed nil ( #377 ) +* Fix embedded primitive type encoding using alias ( #378 ) +* Fix slice/array type encoding with types implementing MarshalJSON ( #379 ) +* Fix unicode decoding when the expected buffer state is not met after reading ( #380 ) + +# v0.9.8 - 2022/06/30 + +### Fix bugs + +* Fix decoding of surrogate-pair ( #365 ) +* Fix handling of embedded primitive type ( #366 ) +* Add validation of escape sequence for decoder ( #367 ) +* Fix stream tokenizing respecting UseNumber ( #369 ) +* Fix encoding when struct pointer type that implements Marshal JSON is embedded ( #375 ) + +### Improve performance + +* Improve performance of linkRecursiveCode ( #368 ) + +# v0.9.7 - 2022/04/22 + +### Fix bugs + +#### Encoder + +* Add filtering process for encoding on slow path ( #355 ) +* Fix encoding of interface{} with pointer type ( #363 ) + +#### Decoder + +* Fix map key decoder that implements UnmarshalJSON ( #353 ) +* Fix decoding of []uint8 type ( #361 ) + +### New features + +* Add DebugWith option for encoder ( #356 ) + +# v0.9.6 - 2022/03/22 + +### Fix bugs + +* Correct the handling of the minimum value of int type for decoder ( #344 ) +* Fix bugs of stream decoder's bufferSize ( #349 ) +* Add a guard to use typeptr more safely ( #351 ) + +### Improve decoder performance + +* Improve escapeString's performance ( #345 ) + +### Others + +* Update go version for CI ( #347 ) + +# v0.9.5 - 2022/03/04 + +### Fix bugs + +* Fix panic when decoding time.Time with context ( #328 ) +* Fix reading the next character in buffer to nul consideration ( #338 ) +* Fix incorrect handling on skipValue ( #341 ) + +### Improve decoder performance + +* Improve performance when a payload contains escape sequence ( #334 ) + +# v0.9.4 - 2022/01/21 + +* Fix IsNilForMarshaler for string type with omitempty ( #323 ) +* Fix the case where the embedded field is at the end ( #326 ) + +# v0.9.3 - 2022/01/14 + +* Fix logic of removing struct field for decoder ( #322 ) + +# v0.9.2 - 2022/01/14 + +* Add invalid decoder to delay type error judgment at decode ( #321 ) + +# v0.9.1 - 2022/01/11 + +* Fix encoding of MarshalText/MarshalJSON operation with head offset ( #319 ) + +# v0.9.0 - 2022/01/05 + +### New feature + +* Supports dynamic filtering of struct fields ( #314 ) + +### Improve encoding performance + +* Improve map encoding performance ( #310 ) +* Optimize encoding path for escaped string ( #311 ) +* Add encoding option for performance ( #312 ) + +### Fix bugs + +* Fix panic at encoding map value on 1.18 ( #310 ) +* Fix MarshalIndent for interface type ( #317 ) + +# v0.8.1 - 2021/12/05 + +* Fix operation conversion from PtrHead to Head in Recursive type ( #305 ) + +# v0.8.0 - 2021/12/02 + +* Fix embedded field conflict behavior ( #300 ) +* Refactor compiler for encoder ( #301 #302 ) + +# v0.7.10 - 2021/10/16 + +* Fix conversion from pointer to uint64 ( #294 ) + +# v0.7.9 - 2021/09/28 + +* Fix encoding of nil value about interface type that has method ( #291 ) + +# v0.7.8 - 2021/09/01 + +* Fix mapassign_faststr for indirect struct type ( #283 ) +* Fix encoding of not empty interface type ( #284 ) +* Fix encoding of empty struct interface type ( #286 ) + +# v0.7.7 - 2021/08/25 + +* Fix invalid utf8 on stream decoder ( #279 ) +* Fix buffer length bug on string stream decoder ( #280 ) + +Thank you @orisano !! + +# v0.7.6 - 2021/08/13 + +* Fix nil slice assignment ( #276 ) +* Improve error message ( #277 ) + +# v0.7.5 - 2021/08/12 + +* Fix encoding of embedded struct with tags ( #265 ) +* Fix encoding of embedded struct that isn't first field ( #272 ) +* Fix decoding of binary type with escaped char ( #273 ) + +# v0.7.4 - 2021/07/06 + +* Fix encoding of indirect layout structure ( #264 ) + +# v0.7.3 - 2021/06/29 + +* Fix encoding of pointer type in empty interface ( #262 ) + +# v0.7.2 - 2021/06/26 + +### Fix decoder + +* Add decoder for func type to fix decoding of nil function value ( #257 ) +* Fix stream decoding of []byte type ( #258 ) + +### Performance + +* Improve decoding performance of map[string]interface{} type ( use `mapassign_faststr` ) ( #256 ) +* Improve encoding performance of empty interface type ( remove recursive calling of `vm.Run` ) ( #259 ) + +### Benchmark + +* Add bytedance/sonic as benchmark target ( #254 ) + +# v0.7.1 - 2021/06/18 + +### Fix decoder + +* Fix error when unmarshal empty array ( #253 ) + +# v0.7.0 - 2021/06/12 + +### Support context for MarshalJSON and UnmarshalJSON ( #248 ) + +* json.MarshalContext(context.Context, interface{}, ...json.EncodeOption) ([]byte, error) +* json.NewEncoder(io.Writer).EncodeContext(context.Context, interface{}, ...json.EncodeOption) error +* json.UnmarshalContext(context.Context, []byte, interface{}, ...json.DecodeOption) error +* json.NewDecoder(io.Reader).DecodeContext(context.Context, interface{}) error + +```go +type MarshalerContext interface { + MarshalJSON(context.Context) ([]byte, error) +} + +type UnmarshalerContext interface { + UnmarshalJSON(context.Context, []byte) error +} +``` + +### Add DecodeFieldPriorityFirstWin option ( #242 ) + +In the default behavior, go-json, like encoding/json, will reflect the result of the last evaluation when a field with the same name exists. I've added new options to allow you to change this behavior. `json.DecodeFieldPriorityFirstWin` option reflects the result of the first evaluation if a field with the same name exists. This behavior has a performance advantage as it allows the subsequent strings to be skipped if all fields have been evaluated. + +### Fix encoder + +* Fix indent number contains recursive type ( #249 ) +* Fix encoding of using empty interface as map key ( #244 ) + +### Fix decoder + +* Fix decoding fields containing escaped characters ( #237 ) + +### Refactor + +* Move some tests to subdirectory ( #243 ) +* Refactor package layout for decoder ( #238 ) + +# v0.6.1 - 2021/06/02 + +### Fix encoder + +* Fix value of totalLength for encoding ( #236 ) + +# v0.6.0 - 2021/06/01 + +### Support Colorize option for encoding (#233) + +```go +b, err := json.MarshalWithOption(v, json.Colorize(json.DefaultColorScheme)) +if err != nil { + ... +} +fmt.Println(string(b)) // print colored json +``` + +### Refactor + +* Fix opcode layout - Adjust memory layout of the opcode to 128 bytes in a 64-bit environment ( #230 ) +* Refactor encode option ( #231 ) +* Refactor escape string ( #232 ) + +# v0.5.1 - 2021/5/20 + +### Optimization + +* Add type addrShift to enable bigger encoder/decoder cache ( #213 ) + +### Fix decoder + +* Keep original reference of slice element ( #229 ) + +### Refactor + +* Refactor Debug mode for encoding ( #226 ) +* Generate VM sources for encoding ( #227 ) +* Refactor validator for null/true/false for decoding ( #221 ) + +# v0.5.0 - 2021/5/9 + +### Supports using omitempty and string tags at the same time ( #216 ) + +### Fix decoder + +* Fix stream decoder for unicode char ( #215 ) +* Fix decoding of slice element ( #219 ) +* Fix calculating of buffer length for stream decoder ( #220 ) + +### Refactor + +* replace skipWhiteSpace goto by loop ( #212 ) + +# v0.4.14 - 2021/5/4 + +### Benchmark + +* Add valyala/fastjson to benchmark ( #193 ) +* Add benchmark task for CI ( #211 ) + +### Fix decoder + +* Fix decoding of slice with unmarshal json type ( #198 ) +* Fix decoding of null value for interface type that does not implement Unmarshaler ( #205 ) +* Fix decoding of null value to []byte by json.Unmarshal ( #206 ) +* Fix decoding of backslash char at the end of string ( #207 ) +* Fix stream decoder for null/true/false value ( #208 ) +* Fix stream decoder for slow reader ( #211 ) + +### Performance + +* If cap of slice is enough, reuse slice data for compatibility with encoding/json ( #200 ) + +# v0.4.13 - 2021/4/20 + +### Fix json.Compact and json.Indent + +* Support validation the input buffer for json.Compact and json.Indent ( #189 ) +* Optimize json.Compact and json.Indent ( improve memory footprint ) ( #190 ) + +# v0.4.12 - 2021/4/15 + +### Fix encoder + +* Fix unnecessary indent for empty slice type ( #181 ) +* Fix encoding of omitempty feature for the slice or interface type ( #183 ) +* Fix encoding custom types zero values with omitempty when marshaller exists ( #187 ) + +### Fix decoder + +* Fix decoder for invalid top level value ( #184 ) +* Fix decoder for invalid number value ( #185 ) + +# v0.4.11 - 2021/4/3 + +* Improve decoder performance for interface type + +# v0.4.10 - 2021/4/2 + +### Fix encoder + +* Fixed a bug when encoding slice and map containing recursive structures +* Fixed a logic to determine if indirect reference + +# v0.4.9 - 2021/3/29 + +### Add debug mode + +If you use `json.MarshalWithOption(v, json.Debug())` and `panic` occurred in `go-json`, produces debug information to console. + +### Support a new feature to compatible with encoding/json + +- invalid UTF-8 is coerced to valid UTF-8 ( without performance down ) + +### Fix encoder + +- Fixed handling of MarshalJSON of function type + +### Fix decoding of slice of pointer type + +If there is a pointer value, go-json will use it. (This behavior is necessary to achieve the ability to prioritize pre-filled values). However, since slices are reused internally, there was a bug that referred to the previous pointer value. Therefore, it is not necessary to refer to the pointer value in advance for the slice element, so we explicitly initialize slice element by `nil`. + +# v0.4.8 - 2021/3/21 + +### Reduce memory usage at compile time + +* go-json have used about 2GB of memory at compile time, but now it can compile with about less than 550MB. + +### Fix any encoder's bug + +* Add many test cases for encoder +* Fix composite type ( slice/array/map ) +* Fix pointer types +* Fix encoding of MarshalJSON or MarshalText or json.Number type + +### Refactor encoder + +* Change package layout for reducing memory usage at compile +* Remove anonymous and only operation +* Remove root property from encodeCompileContext and opcode + +### Fix CI + +* Add Go 1.16 +* Remove Go 1.13 +* Fix `make cover` task + +### Number/Delim/Token/RawMessage use the types defined in encoding/json by type alias + +# v0.4.7 - 2021/02/22 + +### Fix decoder + +* Fix decoding of deep recursive structure +* Fix decoding of embedded unexported pointer field +* Fix invalid test case +* Fix decoding of invalid value +* Fix decoding of prefilled value +* Fix not being able to return UnmarshalTypeError when it should be returned +* Fix decoding of null value +* Fix decoding of type of null string +* Use pre allocated pointer if exists it at decoding + +### Reduce memory usage at compile + +* Integrate int/int8/int16/int32/int64 and uint/uint8/uint16/uint32/uint64 operation to reduce memory usage at compile + +### Remove unnecessary optype diff --git a/vendor/github.com/goccy/go-json/LICENSE b/vendor/github.com/goccy/go-json/LICENSE new file mode 100644 index 000000000..6449c8bff --- /dev/null +++ b/vendor/github.com/goccy/go-json/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Masaaki Goshima + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/goccy/go-json/Makefile b/vendor/github.com/goccy/go-json/Makefile new file mode 100644 index 000000000..5bbfc4c9a --- /dev/null +++ b/vendor/github.com/goccy/go-json/Makefile @@ -0,0 +1,39 @@ +PKG := github.com/goccy/go-json + +BIN_DIR := $(CURDIR)/bin +PKGS := $(shell go list ./... | grep -v internal/cmd|grep -v test) +COVER_PKGS := $(foreach pkg,$(PKGS),$(subst $(PKG),.,$(pkg))) + +COMMA := , +EMPTY := +SPACE := $(EMPTY) $(EMPTY) +COVERPKG_OPT := $(subst $(SPACE),$(COMMA),$(COVER_PKGS)) + +$(BIN_DIR): + @mkdir -p $(BIN_DIR) + +.PHONY: cover +cover: + go test -coverpkg=$(COVERPKG_OPT) -coverprofile=cover.out ./... + +.PHONY: cover-html +cover-html: cover + go tool cover -html=cover.out + +.PHONY: lint +lint: golangci-lint + $(BIN_DIR)/golangci-lint run + +golangci-lint: | $(BIN_DIR) + @{ \ + set -e; \ + GOLANGCI_LINT_TMP_DIR=$$(mktemp -d); \ + cd $$GOLANGCI_LINT_TMP_DIR; \ + go mod init tmp; \ + GOBIN=$(BIN_DIR) go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.48.0; \ + rm -rf $$GOLANGCI_LINT_TMP_DIR; \ + } + +.PHONY: generate +generate: + go generate ./internal/... diff --git a/vendor/github.com/goccy/go-json/README.md b/vendor/github.com/goccy/go-json/README.md new file mode 100644 index 000000000..7bacc54f9 --- /dev/null +++ b/vendor/github.com/goccy/go-json/README.md @@ -0,0 +1,529 @@ +# go-json + +![Go](https://github.com/goccy/go-json/workflows/Go/badge.svg) +[![GoDoc](https://godoc.org/github.com/goccy/go-json?status.svg)](https://pkg.go.dev/github.com/goccy/go-json?tab=doc) +[![codecov](https://codecov.io/gh/goccy/go-json/branch/master/graph/badge.svg)](https://codecov.io/gh/goccy/go-json) + +Fast JSON encoder/decoder compatible with encoding/json for Go + + + +# Roadmap + +``` +* version ( expected release date ) + +* v0.9.0 + | + | while maintaining compatibility with encoding/json, we will add convenient APIs + | + v +* v1.0.0 +``` + +We are accepting requests for features that will be implemented between v0.9.0 and v.1.0.0. +If you have the API you need, please submit your issue [here](https://github.com/goccy/go-json/issues). + +# Features + +- Drop-in replacement of `encoding/json` +- Fast ( See [Benchmark section](https://github.com/goccy/go-json#benchmarks) ) +- Flexible customization with options +- Coloring the encoded string +- Can propagate context.Context to `MarshalJSON` or `UnmarshalJSON` +- Can dynamically filter the fields of the structure type-safely + +# Installation + +``` +go get github.com/goccy/go-json +``` + +# How to use + +Replace import statement from `encoding/json` to `github.com/goccy/go-json` + +``` +-import "encoding/json" ++import "github.com/goccy/go-json" +``` + +# JSON library comparison + +| name | encoder | decoder | compatible with `encoding/json` | +| :----: | :------: | :-----: | :-----------------------------: | +| encoding/json | yes | yes | N/A | +| [json-iterator/go](https://github.com/json-iterator/go) | yes | yes | partial | +| [easyjson](https://github.com/mailru/easyjson) | yes | yes | no | +| [gojay](https://github.com/francoispqt/gojay) | yes | yes | no | +| [segmentio/encoding/json](https://github.com/segmentio/encoding/tree/master/json) | yes | yes | partial | +| [jettison](https://github.com/wI2L/jettison) | yes | no | no | +| [simdjson-go](https://github.com/minio/simdjson-go) | no | yes | no | +| goccy/go-json | yes | yes | yes | + +- `json-iterator/go` isn't compatible with `encoding/json` in many ways (e.g. https://github.com/json-iterator/go/issues/229 ), but it hasn't been supported for a long time. +- `segmentio/encoding/json` is well supported for encoders, but some are not supported for decoder APIs such as `Token` ( streaming decode ) + +## Other libraries + +- [jingo](https://github.com/bet365/jingo) + +I tried the benchmark but it didn't work. +Also, it seems to panic when it receives an unexpected value because there is no error handling... + +- [ffjson](https://github.com/pquerna/ffjson) + +Benchmarking gave very slow results. +It seems that it is assumed that the user will use the buffer pool properly. +Also, development seems to have already stopped + +# Benchmarks + +``` +$ cd benchmarks +$ go test -bench . +``` + +## Encode + + + + +## Decode + + + + + + +# Fuzzing + +[go-json-fuzz](https://github.com/goccy/go-json-fuzz) is the repository for fuzzing tests. +If you run the test in this repository and find a bug, please commit to corpus to go-json-fuzz and report the issue to [go-json](https://github.com/goccy/go-json/issues). + +# How it works + +`go-json` is very fast in both encoding and decoding compared to other libraries. +It's easier to implement by using automatic code generation for performance or by using a dedicated interface, but `go-json` dares to stick to compatibility with `encoding/json` and is the simple interface. Despite this, we are developing with the aim of being the fastest library. + +Here, we explain the various speed-up techniques implemented by `go-json`. + +## Basic technique + +The techniques listed here are the ones used by most of the libraries listed above. + +### Buffer reuse + +Since the only value required for the result of `json.Marshal(interface{}) ([]byte, error)` is `[]byte`, the only value that must be allocated during encoding is the return value `[]byte` . + +Also, as the number of allocations increases, the performance will be affected, so the number of allocations should be kept as low as possible when creating `[]byte`. + +Therefore, there is a technique to reduce the number of times a new buffer must be allocated by reusing the buffer used for the previous encoding by using `sync.Pool`. + +Finally, you allocate a buffer that is as long as the resulting buffer and copy the contents into it, you only need to allocate the buffer once in theory. + +```go +type buffer struct { + data []byte +} + +var bufPool = sync.Pool{ + New: func() interface{} { + return &buffer{data: make([]byte, 0, 1024)} + }, +} + +buf := bufPool.Get().(*buffer) +data := encode(buf.data) // reuse buf.data + +newBuf := make([]byte, len(data)) +copy(newBuf, buf) + +buf.data = data +bufPool.Put(buf) +``` + +### Elimination of reflection + +As you know, the reflection operation is very slow. + +Therefore, using the fact that the address position where the type information is stored is fixed for each binary ( we call this `typeptr` ), +we can use the address in the type information to call a pre-built optimized process. + +For example, you can get the address to the type information from `interface{}` as follows and you can use that information to call a process that does not have reflection. + +To process without reflection, pass a pointer (`unsafe.Pointer`) to the value is stored. + +```go + +type emptyInterface struct { + typ unsafe.Pointer + ptr unsafe.Pointer +} + +var typeToEncoder = map[uintptr]func(unsafe.Pointer)([]byte, error){} + +func Marshal(v interface{}) ([]byte, error) { + iface := (*emptyInterface)(unsafe.Pointer(&v) + typeptr := uintptr(iface.typ) + if enc, exists := typeToEncoder[typeptr]; exists { + return enc(iface.ptr) + } + ... +} +``` + +※ In reality, `typeToEncoder` can be referenced by multiple goroutines, so exclusive control is required. + +## Unique speed-up technique + +## Encoder + +### Do not escape arguments of `Marshal` + +`json.Marshal` and `json.Unmarshal` receive `interface{}` value and they perform type determination dynamically to process. +In normal case, you need to use the `reflect` library to determine the type dynamically, but since `reflect.Type` is defined as `interface`, when you call the method of `reflect.Type`, The reflect's argument is escaped. + +Therefore, the arguments for `Marshal` and `Unmarshal` are always escaped to the heap. +However, `go-json` can use the feature of `reflect.Type` while avoiding escaping. + +`reflect.Type` is defined as `interface`, but in reality `reflect.Type` is implemented only by the structure `rtype` defined in the `reflect` package. +For this reason, to date `reflect.Type` is the same as `*reflect.rtype`. + +Therefore, by directly handling `*reflect.rtype`, which is an implementation of `reflect.Type`, it is possible to avoid escaping because it changes from `interface` to using `struct`. + +The technique for working with `*reflect.rtype` directly from `go-json` is implemented at [rtype.go](https://github.com/goccy/go-json/blob/master/internal/runtime/rtype.go) + +Also, the same technique is cut out as a library ( https://github.com/goccy/go-reflect ) + +Initially this feature was the default behavior of `go-json`. +But after careful testing, I found that I passed a large value to `json.Marshal()` and if the argument could not be assigned to the stack, it could not be properly escaped to the heap (a bug in the Go compiler). + +Therefore, this feature will be provided as an **optional** until this issue is resolved. + +To use it, add `NoEscape` like `MarshalNoEscape()` + +### Encoding using opcode sequence + +I explained that you can use `typeptr` to call a pre-built process from type information. + +In other libraries, this dedicated process is processed by making it an function calling like anonymous function, but function calls are inherently slow processes and should be avoided as much as possible. + +Therefore, `go-json` adopted the Instruction-based execution processing system, which is also used to implement virtual machines for programming language. + +If it is the first type to encode, create the opcode ( instruction ) sequence required for encoding. +From the second time onward, use `typeptr` to get the cached pre-built opcode sequence and encode it based on it. An example of the opcode sequence is shown below. + +```go +json.Marshal(struct{ + X int `json:"x"` + Y string `json:"y"` +}{X: 1, Y: "hello"}) +``` + +When encoding a structure like the one above, create a sequence of opcodes like this: + +``` +- opStructFieldHead ( `{` ) +- opStructFieldInt ( `"x": 1,` ) +- opStructFieldString ( `"y": "hello"` ) +- opStructEnd ( `}` ) +- opEnd +``` + +※ When processing each operation, write the letters on the right. + +In addition, each opcode is managed by the following structure ( +Pseudo code ). + +```go +type opType int +const ( + opStructFieldHead opType = iota + opStructFieldInt + opStructFieldStirng + opStructEnd + opEnd +) +type opcode struct { + op opType + key []byte + next *opcode +} +``` + +The process of encoding using the opcode sequence is roughly implemented as follows. + +```go +func encode(code *opcode, b []byte, p unsafe.Pointer) ([]byte, error) { + for { + switch code.op { + case opStructFieldHead: + b = append(b, '{') + code = code.next + case opStructFieldInt: + b = append(b, code.key...) + b = appendInt((*int)(unsafe.Pointer(uintptr(p)+code.offset))) + code = code.next + case opStructFieldString: + b = append(b, code.key...) + b = appendString((*string)(unsafe.Pointer(uintptr(p)+code.offset))) + code = code.next + case opStructEnd: + b = append(b, '}') + code = code.next + case opEnd: + goto END + } + } +END: + return b, nil +} +``` + +In this way, the huge `switch-case` is used to encode by manipulating the linked list opcodes to avoid unnecessary function calls. + +### Opcode sequence optimization + +One of the advantages of encoding using the opcode sequence is the ease of optimization. +The opcode sequence mentioned above is actually converted into the following optimized operations and used. + +``` +- opStructFieldHeadInt ( `{"x": 1,` ) +- opStructEndString ( `"y": "hello"}` ) +- opEnd +``` + +It has been reduced from 5 opcodes to 3 opcodes ! +Reducing the number of opcodees means reducing the number of branches with `switch-case`. +In other words, the closer the number of operations is to 1, the faster the processing can be performed. + +In `go-json`, optimization to reduce the number of opcodes itself like the above and it speeds up by preparing opcodes with optimized paths. + +### Change recursive call from CALL to JMP + +Recursive processing is required during encoding if the type is defined recursively as follows: + +```go +type T struct { + X int + U *U +} + +type U struct { + T *T +} + +b, err := json.Marshal(&T{ + X: 1, + U: &U{ + T: &T{ + X: 2, + }, + }, +}) +fmt.Println(string(b)) // {"X":1,"U":{"T":{"X":2,"U":null}}} +``` + +In `go-json`, recursive processing is processed by the operation type of ` opStructFieldRecursive`. + +In this operation, after acquiring the opcode sequence used for recursive processing, the function is **not** called recursively as it is, but the necessary values ​​are saved by itself and implemented by moving to the next operation. + +The technique of implementing recursive processing with the `JMP` operation while avoiding the `CALL` operation is a famous technique for implementing a high-speed virtual machine. + +For more details, please refer to [the article](https://engineering.mercari.com/blog/entry/1599563768-081104c850) ( but Japanese only ). + +### Dispatch by typeptr from map to slice + +When retrieving the data cached from the type information by `typeptr`, we usually use map. +Map requires exclusive control, so use `sync.Map` for a naive implementation. + +However, this is slow, so it's a good idea to use the `atomic` package for exclusive control as implemented by `segmentio/encoding/json` ( https://github.com/segmentio/encoding/blob/master/json/codec.go#L41-L55 ). + +This implementation slows down the set instead of speeding up the get, but it works well because of the nature of the library, it encodes much more for the same type. + +However, as a result of profiling, I noticed that `runtime.mapaccess2` accounts for a significant percentage of the execution time. So I thought if I could change the lookup from map to slice. + +There is an API named `typelinks` defined in the `runtime` package that the `reflect` package uses internally. +This allows you to get all the type information defined in the binary at runtime. + +The fact that all type information can be acquired means that by constructing slices in advance with the acquired total number of type information, it is possible to look up with the value of `typeptr` without worrying about out-of-range access. + +However, if there is too much type information, it will use a lot of memory, so by default we will only use this optimization if the slice size fits within **2Mib** . + +If this approach is not available, it will fall back to the `atomic` based process described above. + +If you want to know more, please refer to the implementation [here](https://github.com/goccy/go-json/blob/master/internal/runtime/type.go#L36-L100) + +## Decoder + +### Dispatch by typeptr from map to slice + +Like the encoder, the decoder also uses typeptr to call the dedicated process. + +### Faster termination character inspection using NUL character + +In order to decode, you have to traverse the input buffer character by position. +At that time, if you check whether the buffer has reached the end, it will be very slow. + +`buf` : `[]byte` type variable. holds the string passed to the decoder +`cursor` : `int64` type variable. holds the current read position + +```go +buflen := len(buf) +for ; cursor < buflen; cursor++ { // compare cursor and buflen at all times, it is so slow. + switch buf[cursor] { + case ' ', '\n', '\r', '\t': + } +} +``` + +Therefore, by adding the `NUL` (`\000`) character to the end of the read buffer as shown below, it is possible to check the termination character at the same time as other characters. + +```go +for { + switch buf[cursor] { + case ' ', '\n', '\r', '\t': + case '\000': + return nil + } + cursor++ +} +``` + +### Use Boundary Check Elimination + +Due to the `NUL` character optimization, the Go compiler does a boundary check every time, even though `buf[cursor]` does not cause out-of-range access. + +Therefore, `go-json` eliminates boundary check by fetching characters for hotspot by pointer operation. For example, the following code. + +```go +func char(ptr unsafe.Pointer, offset int64) byte { + return *(*byte)(unsafe.Pointer(uintptr(ptr) + uintptr(offset))) +} + +p := (*sliceHeader)(&unsafe.Pointer(buf)).data +for { + switch char(p, cursor) { + case ' ', '\n', '\r', '\t': + case '\000': + return nil + } + cursor++ +} +``` + +### Checking the existence of fields of struct using Bitmaps + +I found by the profiling result, in the struct decode, lookup process for field was taking a long time. + +For example, consider decoding a string like `{"a":1,"b":2,"c":3}` into the following structure: + +```go +type T struct { + A int `json:"a"` + B int `json:"b"` + C int `json:"c"` +} +``` + +At this time, it was found that it takes a lot of time to acquire the decoding process corresponding to the field from the field name as shown below during the decoding process. + +```go +fieldName := decodeKey(buf, cursor) // "a" or "b" or "c" +decoder, exists := fieldToDecoderMap[fieldName] // so slow +if exists { + decoder(buf, cursor) +} else { + skipValue(buf, cursor) +} +``` + +To improve this process, `json-iterator/go` is optimized so that it can be branched by switch-case when the number of fields in the structure is 10 or less (switch-case is faster than map). However, there is a risk of hash collision because the value hashed by the FNV algorithm is used for conditional branching. Also, `gojay` processes this part at high speed by letting the library user yourself write `switch-case`. + + +`go-json` considers and implements a new approach that is different from these. I call this **bitmap field optimization**. + +The range of values ​​per character can be represented by `[256]byte`. Also, if the number of fields in the structure is 8 or less, `int8` type can represent the state of each field. +In other words, it has the following structure. + +- Base ( 8bit ): `00000000` +- Key "a": `00000001` ( assign key "a" to the first bit ) +- Key "b": `00000010` ( assign key "b" to the second bit ) +- Key "c": `00000100` ( assign key "c" to the third bit ) + +Bitmap structure is the following + +``` + | key index(0) | +------------------------ + 0 | 00000000 | + 1 | 00000000 | +~~ | | +97 (a) | 00000001 | +98 (b) | 00000010 | +99 (c) | 00000100 | +~~ | | +255 | 00000000 | +``` + +You can think of this as a Bitmap with a height of `256` and a width of the maximum string length in the field name. +In other words, it can be represented by the following type . + +```go +[maxFieldKeyLength][256]int8 +``` + +When decoding a field character, check whether the corresponding character exists by referring to the pre-built bitmap like the following. + +```go +var curBit int8 = math.MaxInt8 // 11111111 + +c := char(buf, cursor) +bit := bitmap[keyIdx][c] +curBit &= bit +if curBit == 0 { + // not found field +} +``` + +If `curBit` is not `0` until the end of the field string, then the string is +You may have hit one of the fields. +But the possibility is that if the decoded string is shorter than the field string, you will get a false hit. + +- input: `{"a":1}` +```go +type T struct { + X int `json:"abc"` +} +``` +※ Since `a` is shorter than `abc`, it can decode to the end of the field character without `curBit` being 0. + +Rest assured. In this case, it doesn't matter because you can tell if you hit by comparing the string length of `a` with the string length of `abc`. + +Finally, calculate the position of the bit where `1` is set and get the corresponding value, and you're done. + +Using this technique, field lookups are possible with only bitwise operations and access to slices. + +`go-json` uses a similar technique for fields with 9 or more and 16 or less fields. At this time, Bitmap is constructed as `[maxKeyLen][256]int16` type. + +Currently, this optimization is not performed when the maximum length of the field name is long (specifically, 64 bytes or more) in addition to the limitation of the number of fields from the viewpoint of saving memory usage. + +### Others + +I have done a lot of other optimizations. I will find time to write about them. If you have any questions about what's written here or other optimizations, please visit the `#go-json` channel on `gophers.slack.com` . + +## Reference + +Regarding the story of go-json, there are the following articles in Japanese only. + +- https://speakerdeck.com/goccy/zui-su-falsejsonraiburariwoqiu-mete +- https://engineering.mercari.com/blog/entry/1599563768-081104c850/ + +# Looking for Sponsors + +I'm looking for sponsors this library. This library is being developed as a personal project in my spare time. If you want a quick response or problem resolution when using this library in your project, please register as a [sponsor](https://github.com/sponsors/goccy). I will cooperate as much as possible. Of course, this library is developed as an MIT license, so you can use it freely for free. + +# License + +MIT diff --git a/vendor/github.com/goccy/go-json/color.go b/vendor/github.com/goccy/go-json/color.go new file mode 100644 index 000000000..e80b22b48 --- /dev/null +++ b/vendor/github.com/goccy/go-json/color.go @@ -0,0 +1,68 @@ +package json + +import ( + "fmt" + + "github.com/goccy/go-json/internal/encoder" +) + +type ( + ColorFormat = encoder.ColorFormat + ColorScheme = encoder.ColorScheme +) + +const escape = "\x1b" + +type colorAttr int + +//nolint:deadcode,varcheck +const ( + fgBlackColor colorAttr = iota + 30 + fgRedColor + fgGreenColor + fgYellowColor + fgBlueColor + fgMagentaColor + fgCyanColor + fgWhiteColor +) + +//nolint:deadcode,varcheck +const ( + fgHiBlackColor colorAttr = iota + 90 + fgHiRedColor + fgHiGreenColor + fgHiYellowColor + fgHiBlueColor + fgHiMagentaColor + fgHiCyanColor + fgHiWhiteColor +) + +func createColorFormat(attr colorAttr) ColorFormat { + return ColorFormat{ + Header: wrapColor(attr), + Footer: resetColor(), + } +} + +func wrapColor(attr colorAttr) string { + return fmt.Sprintf("%s[%dm", escape, attr) +} + +func resetColor() string { + return wrapColor(colorAttr(0)) +} + +var ( + DefaultColorScheme = &ColorScheme{ + Int: createColorFormat(fgHiMagentaColor), + Uint: createColorFormat(fgHiMagentaColor), + Float: createColorFormat(fgHiMagentaColor), + Bool: createColorFormat(fgHiYellowColor), + String: createColorFormat(fgHiGreenColor), + Binary: createColorFormat(fgHiRedColor), + ObjectKey: createColorFormat(fgHiCyanColor), + Null: createColorFormat(fgBlueColor), + } +) diff --git a/vendor/github.com/goccy/go-json/decode.go b/vendor/github.com/goccy/go-json/decode.go new file mode 100644 index 000000000..74c6ac3bc --- /dev/null +++ b/vendor/github.com/goccy/go-json/decode.go @@ -0,0 +1,263 @@ +package json + +import ( + "context" + "fmt" + "io" + "reflect" + "unsafe" + + "github.com/goccy/go-json/internal/decoder" + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type Decoder struct { + s *decoder.Stream +} + +const ( + nul = '\000' +) + +type emptyInterface struct { + typ *runtime.Type + ptr unsafe.Pointer +} + +func unmarshal(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { + src := make([]byte, len(data)+1) // append nul byte to the end + copy(src, data) + + header := (*emptyInterface)(unsafe.Pointer(&v)) + + if err := validateType(header.typ, uintptr(header.ptr)); err != nil { + return err + } + dec, err := decoder.CompileToGetDecoder(header.typ) + if err != nil { + return err + } + ctx := decoder.TakeRuntimeContext() + ctx.Buf = src + ctx.Option.Flags = 0 + for _, optFunc := range optFuncs { + optFunc(ctx.Option) + } + cursor, err := dec.Decode(ctx, 0, 0, header.ptr) + if err != nil { + decoder.ReleaseRuntimeContext(ctx) + return err + } + decoder.ReleaseRuntimeContext(ctx) + return validateEndBuf(src, cursor) +} + +func unmarshalContext(ctx context.Context, data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { + src := make([]byte, len(data)+1) // append nul byte to the end + copy(src, data) + + header := (*emptyInterface)(unsafe.Pointer(&v)) + + if err := validateType(header.typ, uintptr(header.ptr)); err != nil { + return err + } + dec, err := decoder.CompileToGetDecoder(header.typ) + if err != nil { + return err + } + rctx := decoder.TakeRuntimeContext() + rctx.Buf = src + rctx.Option.Flags = 0 + rctx.Option.Flags |= decoder.ContextOption + rctx.Option.Context = ctx + for _, optFunc := range optFuncs { + optFunc(rctx.Option) + } + cursor, err := dec.Decode(rctx, 0, 0, header.ptr) + if err != nil { + decoder.ReleaseRuntimeContext(rctx) + return err + } + decoder.ReleaseRuntimeContext(rctx) + return validateEndBuf(src, cursor) +} + +var ( + pathDecoder = decoder.NewPathDecoder() +) + +func extractFromPath(path *Path, data []byte, optFuncs ...DecodeOptionFunc) ([][]byte, error) { + if path.path.RootSelectorOnly { + return [][]byte{data}, nil + } + src := make([]byte, len(data)+1) // append nul byte to the end + copy(src, data) + + ctx := decoder.TakeRuntimeContext() + ctx.Buf = src + ctx.Option.Flags = 0 + ctx.Option.Flags |= decoder.PathOption + ctx.Option.Path = path.path + for _, optFunc := range optFuncs { + optFunc(ctx.Option) + } + paths, cursor, err := pathDecoder.DecodePath(ctx, 0, 0) + if err != nil { + decoder.ReleaseRuntimeContext(ctx) + return nil, err + } + decoder.ReleaseRuntimeContext(ctx) + if err := validateEndBuf(src, cursor); err != nil { + return nil, err + } + return paths, nil +} + +func unmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { + src := make([]byte, len(data)+1) // append nul byte to the end + copy(src, data) + + header := (*emptyInterface)(unsafe.Pointer(&v)) + + if err := validateType(header.typ, uintptr(header.ptr)); err != nil { + return err + } + dec, err := decoder.CompileToGetDecoder(header.typ) + if err != nil { + return err + } + + ctx := decoder.TakeRuntimeContext() + ctx.Buf = src + ctx.Option.Flags = 0 + for _, optFunc := range optFuncs { + optFunc(ctx.Option) + } + cursor, err := dec.Decode(ctx, 0, 0, noescape(header.ptr)) + if err != nil { + decoder.ReleaseRuntimeContext(ctx) + return err + } + decoder.ReleaseRuntimeContext(ctx) + return validateEndBuf(src, cursor) +} + +func validateEndBuf(src []byte, cursor int64) error { + for { + switch src[cursor] { + case ' ', '\t', '\n', '\r': + cursor++ + continue + case nul: + return nil + } + return errors.ErrSyntax( + fmt.Sprintf("invalid character '%c' after top-level value", src[cursor]), + cursor+1, + ) + } +} + +//nolint:staticcheck +//go:nosplit +func noescape(p unsafe.Pointer) unsafe.Pointer { + x := uintptr(p) + return unsafe.Pointer(x ^ 0) +} + +func validateType(typ *runtime.Type, p uintptr) error { + if typ == nil || typ.Kind() != reflect.Ptr || p == 0 { + return &InvalidUnmarshalError{Type: runtime.RType2Type(typ)} + } + return nil +} + +// NewDecoder returns a new decoder that reads from r. +// +// The decoder introduces its own buffering and may +// read data from r beyond the JSON values requested. +func NewDecoder(r io.Reader) *Decoder { + s := decoder.NewStream(r) + return &Decoder{ + s: s, + } +} + +// Buffered returns a reader of the data remaining in the Decoder's +// buffer. The reader is valid until the next call to Decode. +func (d *Decoder) Buffered() io.Reader { + return d.s.Buffered() +} + +// Decode reads the next JSON-encoded value from its +// input and stores it in the value pointed to by v. +// +// See the documentation for Unmarshal for details about +// the conversion of JSON into a Go value. +func (d *Decoder) Decode(v interface{}) error { + return d.DecodeWithOption(v) +} + +// DecodeContext reads the next JSON-encoded value from its +// input and stores it in the value pointed to by v with context.Context. +func (d *Decoder) DecodeContext(ctx context.Context, v interface{}) error { + d.s.Option.Flags |= decoder.ContextOption + d.s.Option.Context = ctx + return d.DecodeWithOption(v) +} + +func (d *Decoder) DecodeWithOption(v interface{}, optFuncs ...DecodeOptionFunc) error { + header := (*emptyInterface)(unsafe.Pointer(&v)) + typ := header.typ + ptr := uintptr(header.ptr) + typeptr := uintptr(unsafe.Pointer(typ)) + // noescape trick for header.typ ( reflect.*rtype ) + copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr)) + + if err := validateType(copiedType, ptr); err != nil { + return err + } + + dec, err := decoder.CompileToGetDecoder(typ) + if err != nil { + return err + } + if err := d.s.PrepareForDecode(); err != nil { + return err + } + s := d.s + for _, optFunc := range optFuncs { + optFunc(s.Option) + } + if err := dec.DecodeStream(s, 0, header.ptr); err != nil { + return err + } + s.Reset() + return nil +} + +func (d *Decoder) More() bool { + return d.s.More() +} + +func (d *Decoder) Token() (Token, error) { + return d.s.Token() +} + +// DisallowUnknownFields causes the Decoder to return an error when the destination +// is a struct and the input contains object keys which do not match any +// non-ignored, exported fields in the destination. +func (d *Decoder) DisallowUnknownFields() { + d.s.DisallowUnknownFields = true +} + +func (d *Decoder) InputOffset() int64 { + return d.s.TotalOffset() +} + +// UseNumber causes the Decoder to unmarshal a number into an interface{} as a +// Number instead of as a float64. +func (d *Decoder) UseNumber() { + d.s.UseNumber = true +} diff --git a/vendor/github.com/goccy/go-json/docker-compose.yml b/vendor/github.com/goccy/go-json/docker-compose.yml new file mode 100644 index 000000000..db40c79ad --- /dev/null +++ b/vendor/github.com/goccy/go-json/docker-compose.yml @@ -0,0 +1,13 @@ +version: '2' +services: + go-json: + image: golang:1.18 + volumes: + - '.:/go/src/go-json' + deploy: + resources: + limits: + memory: 620M + working_dir: /go/src/go-json + command: | + sh -c "go test -c . && ls go-json.test" diff --git a/vendor/github.com/goccy/go-json/encode.go b/vendor/github.com/goccy/go-json/encode.go new file mode 100644 index 000000000..4bd899f38 --- /dev/null +++ b/vendor/github.com/goccy/go-json/encode.go @@ -0,0 +1,326 @@ +package json + +import ( + "context" + "io" + "os" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/encoder/vm" + "github.com/goccy/go-json/internal/encoder/vm_color" + "github.com/goccy/go-json/internal/encoder/vm_color_indent" + "github.com/goccy/go-json/internal/encoder/vm_indent" +) + +// An Encoder writes JSON values to an output stream. +type Encoder struct { + w io.Writer + enabledIndent bool + enabledHTMLEscape bool + prefix string + indentStr string +} + +// NewEncoder returns a new encoder that writes to w. +func NewEncoder(w io.Writer) *Encoder { + return &Encoder{w: w, enabledHTMLEscape: true} +} + +// Encode writes the JSON encoding of v to the stream, followed by a newline character. +// +// See the documentation for Marshal for details about the conversion of Go values to JSON. +func (e *Encoder) Encode(v interface{}) error { + return e.EncodeWithOption(v) +} + +// EncodeWithOption call Encode with EncodeOption. +func (e *Encoder) EncodeWithOption(v interface{}, optFuncs ...EncodeOptionFunc) error { + ctx := encoder.TakeRuntimeContext() + ctx.Option.Flag = 0 + + err := e.encodeWithOption(ctx, v, optFuncs...) + + encoder.ReleaseRuntimeContext(ctx) + return err +} + +// EncodeContext call Encode with context.Context and EncodeOption. +func (e *Encoder) EncodeContext(ctx context.Context, v interface{}, optFuncs ...EncodeOptionFunc) error { + rctx := encoder.TakeRuntimeContext() + rctx.Option.Flag = 0 + rctx.Option.Flag |= encoder.ContextOption + rctx.Option.Context = ctx + + err := e.encodeWithOption(rctx, v, optFuncs...) + + encoder.ReleaseRuntimeContext(rctx) + return err +} + +func (e *Encoder) encodeWithOption(ctx *encoder.RuntimeContext, v interface{}, optFuncs ...EncodeOptionFunc) error { + if e.enabledHTMLEscape { + ctx.Option.Flag |= encoder.HTMLEscapeOption + } + ctx.Option.Flag |= encoder.NormalizeUTF8Option + ctx.Option.DebugOut = os.Stdout + for _, optFunc := range optFuncs { + optFunc(ctx.Option) + } + var ( + buf []byte + err error + ) + if e.enabledIndent { + buf, err = encodeIndent(ctx, v, e.prefix, e.indentStr) + } else { + buf, err = encode(ctx, v) + } + if err != nil { + return err + } + if e.enabledIndent { + buf = buf[:len(buf)-2] + } else { + buf = buf[:len(buf)-1] + } + buf = append(buf, '\n') + if _, err := e.w.Write(buf); err != nil { + return err + } + return nil +} + +// SetEscapeHTML specifies whether problematic HTML characters should be escaped inside JSON quoted strings. +// The default behavior is to escape &, <, and > to \u0026, \u003c, and \u003e to avoid certain safety problems that can arise when embedding JSON in HTML. +// +// In non-HTML settings where the escaping interferes with the readability of the output, SetEscapeHTML(false) disables this behavior. +func (e *Encoder) SetEscapeHTML(on bool) { + e.enabledHTMLEscape = on +} + +// SetIndent instructs the encoder to format each subsequent encoded value as if indented by the package-level function Indent(dst, src, prefix, indent). +// Calling SetIndent("", "") disables indentation. +func (e *Encoder) SetIndent(prefix, indent string) { + if prefix == "" && indent == "" { + e.enabledIndent = false + return + } + e.prefix = prefix + e.indentStr = indent + e.enabledIndent = true +} + +func marshalContext(ctx context.Context, v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) { + rctx := encoder.TakeRuntimeContext() + rctx.Option.Flag = 0 + rctx.Option.Flag = encoder.HTMLEscapeOption | encoder.NormalizeUTF8Option | encoder.ContextOption + rctx.Option.Context = ctx + for _, optFunc := range optFuncs { + optFunc(rctx.Option) + } + + buf, err := encode(rctx, v) + if err != nil { + encoder.ReleaseRuntimeContext(rctx) + return nil, err + } + + // this line exists to escape call of `runtime.makeslicecopy` . + // if use `make([]byte, len(buf)-1)` and `copy(copied, buf)`, + // dst buffer size and src buffer size are differrent. + // in this case, compiler uses `runtime.makeslicecopy`, but it is slow. + buf = buf[:len(buf)-1] + copied := make([]byte, len(buf)) + copy(copied, buf) + + encoder.ReleaseRuntimeContext(rctx) + return copied, nil +} + +func marshal(v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) { + ctx := encoder.TakeRuntimeContext() + + ctx.Option.Flag = 0 + ctx.Option.Flag |= (encoder.HTMLEscapeOption | encoder.NormalizeUTF8Option) + for _, optFunc := range optFuncs { + optFunc(ctx.Option) + } + + buf, err := encode(ctx, v) + if err != nil { + encoder.ReleaseRuntimeContext(ctx) + return nil, err + } + + // this line exists to escape call of `runtime.makeslicecopy` . + // if use `make([]byte, len(buf)-1)` and `copy(copied, buf)`, + // dst buffer size and src buffer size are differrent. + // in this case, compiler uses `runtime.makeslicecopy`, but it is slow. + buf = buf[:len(buf)-1] + copied := make([]byte, len(buf)) + copy(copied, buf) + + encoder.ReleaseRuntimeContext(ctx) + return copied, nil +} + +func marshalNoEscape(v interface{}) ([]byte, error) { + ctx := encoder.TakeRuntimeContext() + + ctx.Option.Flag = 0 + ctx.Option.Flag |= (encoder.HTMLEscapeOption | encoder.NormalizeUTF8Option) + + buf, err := encodeNoEscape(ctx, v) + if err != nil { + encoder.ReleaseRuntimeContext(ctx) + return nil, err + } + + // this line exists to escape call of `runtime.makeslicecopy` . + // if use `make([]byte, len(buf)-1)` and `copy(copied, buf)`, + // dst buffer size and src buffer size are differrent. + // in this case, compiler uses `runtime.makeslicecopy`, but it is slow. + buf = buf[:len(buf)-1] + copied := make([]byte, len(buf)) + copy(copied, buf) + + encoder.ReleaseRuntimeContext(ctx) + return copied, nil +} + +func marshalIndent(v interface{}, prefix, indent string, optFuncs ...EncodeOptionFunc) ([]byte, error) { + ctx := encoder.TakeRuntimeContext() + + ctx.Option.Flag = 0 + ctx.Option.Flag |= (encoder.HTMLEscapeOption | encoder.NormalizeUTF8Option | encoder.IndentOption) + for _, optFunc := range optFuncs { + optFunc(ctx.Option) + } + + buf, err := encodeIndent(ctx, v, prefix, indent) + if err != nil { + encoder.ReleaseRuntimeContext(ctx) + return nil, err + } + + buf = buf[:len(buf)-2] + copied := make([]byte, len(buf)) + copy(copied, buf) + + encoder.ReleaseRuntimeContext(ctx) + return copied, nil +} + +func encode(ctx *encoder.RuntimeContext, v interface{}) ([]byte, error) { + b := ctx.Buf[:0] + if v == nil { + b = encoder.AppendNull(ctx, b) + b = encoder.AppendComma(ctx, b) + return b, nil + } + header := (*emptyInterface)(unsafe.Pointer(&v)) + typ := header.typ + + typeptr := uintptr(unsafe.Pointer(typ)) + codeSet, err := encoder.CompileToGetCodeSet(ctx, typeptr) + if err != nil { + return nil, err + } + + p := uintptr(header.ptr) + ctx.Init(p, codeSet.CodeLength) + ctx.KeepRefs = append(ctx.KeepRefs, header.ptr) + + buf, err := encodeRunCode(ctx, b, codeSet) + if err != nil { + return nil, err + } + ctx.Buf = buf + return buf, nil +} + +func encodeNoEscape(ctx *encoder.RuntimeContext, v interface{}) ([]byte, error) { + b := ctx.Buf[:0] + if v == nil { + b = encoder.AppendNull(ctx, b) + b = encoder.AppendComma(ctx, b) + return b, nil + } + header := (*emptyInterface)(unsafe.Pointer(&v)) + typ := header.typ + + typeptr := uintptr(unsafe.Pointer(typ)) + codeSet, err := encoder.CompileToGetCodeSet(ctx, typeptr) + if err != nil { + return nil, err + } + + p := uintptr(header.ptr) + ctx.Init(p, codeSet.CodeLength) + buf, err := encodeRunCode(ctx, b, codeSet) + if err != nil { + return nil, err + } + + ctx.Buf = buf + return buf, nil +} + +func encodeIndent(ctx *encoder.RuntimeContext, v interface{}, prefix, indent string) ([]byte, error) { + b := ctx.Buf[:0] + if v == nil { + b = encoder.AppendNull(ctx, b) + b = encoder.AppendCommaIndent(ctx, b) + return b, nil + } + header := (*emptyInterface)(unsafe.Pointer(&v)) + typ := header.typ + + typeptr := uintptr(unsafe.Pointer(typ)) + codeSet, err := encoder.CompileToGetCodeSet(ctx, typeptr) + if err != nil { + return nil, err + } + + p := uintptr(header.ptr) + ctx.Init(p, codeSet.CodeLength) + buf, err := encodeRunIndentCode(ctx, b, codeSet, prefix, indent) + + ctx.KeepRefs = append(ctx.KeepRefs, header.ptr) + + if err != nil { + return nil, err + } + + ctx.Buf = buf + return buf, nil +} + +func encodeRunCode(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + if (ctx.Option.Flag & encoder.DebugOption) != 0 { + if (ctx.Option.Flag & encoder.ColorizeOption) != 0 { + return vm_color.DebugRun(ctx, b, codeSet) + } + return vm.DebugRun(ctx, b, codeSet) + } + if (ctx.Option.Flag & encoder.ColorizeOption) != 0 { + return vm_color.Run(ctx, b, codeSet) + } + return vm.Run(ctx, b, codeSet) +} + +func encodeRunIndentCode(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, prefix, indent string) ([]byte, error) { + ctx.Prefix = []byte(prefix) + ctx.IndentStr = []byte(indent) + if (ctx.Option.Flag & encoder.DebugOption) != 0 { + if (ctx.Option.Flag & encoder.ColorizeOption) != 0 { + return vm_color_indent.DebugRun(ctx, b, codeSet) + } + return vm_indent.DebugRun(ctx, b, codeSet) + } + if (ctx.Option.Flag & encoder.ColorizeOption) != 0 { + return vm_color_indent.Run(ctx, b, codeSet) + } + return vm_indent.Run(ctx, b, codeSet) +} diff --git a/vendor/github.com/goccy/go-json/error.go b/vendor/github.com/goccy/go-json/error.go new file mode 100644 index 000000000..5b2dcee50 --- /dev/null +++ b/vendor/github.com/goccy/go-json/error.go @@ -0,0 +1,41 @@ +package json + +import ( + "github.com/goccy/go-json/internal/errors" +) + +// Before Go 1.2, an InvalidUTF8Error was returned by Marshal when +// attempting to encode a string value with invalid UTF-8 sequences. +// As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by +// replacing invalid bytes with the Unicode replacement rune U+FFFD. +// +// Deprecated: No longer used; kept for compatibility. +type InvalidUTF8Error = errors.InvalidUTF8Error + +// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. +// (The argument to Unmarshal must be a non-nil pointer.) +type InvalidUnmarshalError = errors.InvalidUnmarshalError + +// A MarshalerError represents an error from calling a MarshalJSON or MarshalText method. +type MarshalerError = errors.MarshalerError + +// A SyntaxError is a description of a JSON syntax error. +type SyntaxError = errors.SyntaxError + +// 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 = errors.UnmarshalFieldError + +// An UnmarshalTypeError describes a JSON value that was +// not appropriate for a value of a specific Go type. +type UnmarshalTypeError = errors.UnmarshalTypeError + +// An UnsupportedTypeError is returned by Marshal when attempting +// to encode an unsupported value type. +type UnsupportedTypeError = errors.UnsupportedTypeError + +type UnsupportedValueError = errors.UnsupportedValueError + +type PathError = errors.PathError diff --git a/vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go b/vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go new file mode 100644 index 000000000..b6876cf0d --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go @@ -0,0 +1,41 @@ +package decoder + +import ( + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +type anonymousFieldDecoder struct { + structType *runtime.Type + offset uintptr + dec Decoder +} + +func newAnonymousFieldDecoder(structType *runtime.Type, offset uintptr, dec Decoder) *anonymousFieldDecoder { + return &anonymousFieldDecoder{ + structType: structType, + offset: offset, + dec: dec, + } +} + +func (d *anonymousFieldDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + if *(*unsafe.Pointer)(p) == nil { + *(*unsafe.Pointer)(p) = unsafe_New(d.structType) + } + p = *(*unsafe.Pointer)(p) + return d.dec.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+d.offset)) +} + +func (d *anonymousFieldDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + if *(*unsafe.Pointer)(p) == nil { + *(*unsafe.Pointer)(p) = unsafe_New(d.structType) + } + p = *(*unsafe.Pointer)(p) + return d.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+d.offset)) +} + +func (d *anonymousFieldDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + return d.dec.DecodePath(ctx, cursor, depth) +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/array.go b/vendor/github.com/goccy/go-json/internal/decoder/array.go new file mode 100644 index 000000000..4b23ed43f --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/array.go @@ -0,0 +1,176 @@ +package decoder + +import ( + "fmt" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type arrayDecoder struct { + elemType *runtime.Type + size uintptr + valueDecoder Decoder + alen int + structName string + fieldName string + zeroValue unsafe.Pointer +} + +func newArrayDecoder(dec Decoder, elemType *runtime.Type, alen int, structName, fieldName string) *arrayDecoder { + // workaround to avoid checkptr errors. cannot use `*(*unsafe.Pointer)(unsafe_New(elemType))` directly. + zeroValuePtr := unsafe_New(elemType) + zeroValue := **(**unsafe.Pointer)(unsafe.Pointer(&zeroValuePtr)) + return &arrayDecoder{ + valueDecoder: dec, + elemType: elemType, + size: elemType.Size(), + alen: alen, + structName: structName, + fieldName: fieldName, + zeroValue: zeroValue, + } +} + +func (d *arrayDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + case 'n': + if err := nullBytes(s); err != nil { + return err + } + return nil + case '[': + idx := 0 + s.cursor++ + if s.skipWhiteSpace() == ']' { + for idx < d.alen { + *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue + idx++ + } + s.cursor++ + return nil + } + for { + if idx < d.alen { + if err := d.valueDecoder.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+uintptr(idx)*d.size)); err != nil { + return err + } + } else { + if err := s.skipValue(depth); err != nil { + return err + } + } + idx++ + switch s.skipWhiteSpace() { + case ']': + for idx < d.alen { + *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue + idx++ + } + s.cursor++ + return nil + case ',': + s.cursor++ + continue + case nul: + if s.read() { + s.cursor++ + continue + } + goto ERROR + default: + goto ERROR + } + } + case nul: + if s.read() { + continue + } + goto ERROR + default: + goto ERROR + } + s.cursor++ + } +ERROR: + return errors.ErrUnexpectedEndOfJSON("array", s.totalOffset()) +} + +func (d *arrayDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + + for { + switch buf[cursor] { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case 'n': + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + return cursor, nil + case '[': + idx := 0 + cursor++ + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == ']' { + for idx < d.alen { + *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue + idx++ + } + cursor++ + return cursor, nil + } + for { + if idx < d.alen { + c, err := d.valueDecoder.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+uintptr(idx)*d.size)) + if err != nil { + return 0, err + } + cursor = c + } else { + c, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + cursor = c + } + idx++ + cursor = skipWhiteSpace(buf, cursor) + switch buf[cursor] { + case ']': + for idx < d.alen { + *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue + idx++ + } + cursor++ + return cursor, nil + case ',': + cursor++ + continue + default: + return 0, errors.ErrInvalidCharacter(buf[cursor], "array", cursor) + } + } + default: + return 0, errors.ErrUnexpectedEndOfJSON("array", cursor) + } + } +} + +func (d *arrayDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + return nil, 0, fmt.Errorf("json: array decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/assign.go b/vendor/github.com/goccy/go-json/internal/decoder/assign.go new file mode 100644 index 000000000..c53e6ad9f --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/assign.go @@ -0,0 +1,438 @@ +package decoder + +import ( + "fmt" + "reflect" + "strconv" +) + +var ( + nilValue = reflect.ValueOf(nil) +) + +func AssignValue(src, dst reflect.Value) error { + if dst.Type().Kind() != reflect.Ptr { + return fmt.Errorf("invalid dst type. required pointer type: %T", dst.Type()) + } + casted, err := castValue(dst.Elem().Type(), src) + if err != nil { + return err + } + dst.Elem().Set(casted) + return nil +} + +func castValue(t reflect.Type, v reflect.Value) (reflect.Value, error) { + switch t.Kind() { + case reflect.Int: + vv, err := castInt(v) + if err != nil { + return nilValue, err + } + return reflect.ValueOf(int(vv.Int())), nil + case reflect.Int8: + vv, err := castInt(v) + if err != nil { + return nilValue, err + } + return reflect.ValueOf(int8(vv.Int())), nil + case reflect.Int16: + vv, err := castInt(v) + if err != nil { + return nilValue, err + } + return reflect.ValueOf(int16(vv.Int())), nil + case reflect.Int32: + vv, err := castInt(v) + if err != nil { + return nilValue, err + } + return reflect.ValueOf(int32(vv.Int())), nil + case reflect.Int64: + return castInt(v) + case reflect.Uint: + vv, err := castUint(v) + if err != nil { + return nilValue, err + } + return reflect.ValueOf(uint(vv.Uint())), nil + case reflect.Uint8: + vv, err := castUint(v) + if err != nil { + return nilValue, err + } + return reflect.ValueOf(uint8(vv.Uint())), nil + case reflect.Uint16: + vv, err := castUint(v) + if err != nil { + return nilValue, err + } + return reflect.ValueOf(uint16(vv.Uint())), nil + case reflect.Uint32: + vv, err := castUint(v) + if err != nil { + return nilValue, err + } + return reflect.ValueOf(uint32(vv.Uint())), nil + case reflect.Uint64: + return castUint(v) + case reflect.Uintptr: + vv, err := castUint(v) + if err != nil { + return nilValue, err + } + return reflect.ValueOf(uintptr(vv.Uint())), nil + case reflect.String: + return castString(v) + case reflect.Bool: + return castBool(v) + case reflect.Float32: + vv, err := castFloat(v) + if err != nil { + return nilValue, err + } + return reflect.ValueOf(float32(vv.Float())), nil + case reflect.Float64: + return castFloat(v) + case reflect.Array: + return castArray(t, v) + case reflect.Slice: + return castSlice(t, v) + case reflect.Map: + return castMap(t, v) + case reflect.Struct: + return castStruct(t, v) + } + return v, nil +} + +func castInt(v reflect.Value) (reflect.Value, error) { + switch v.Type().Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v, nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return reflect.ValueOf(int64(v.Uint())), nil + case reflect.String: + i64, err := strconv.ParseInt(v.String(), 10, 64) + if err != nil { + return nilValue, err + } + return reflect.ValueOf(i64), nil + case reflect.Bool: + if v.Bool() { + return reflect.ValueOf(int64(1)), nil + } + return reflect.ValueOf(int64(0)), nil + case reflect.Float32, reflect.Float64: + return reflect.ValueOf(int64(v.Float())), nil + case reflect.Array: + if v.Len() > 0 { + return castInt(v.Index(0)) + } + return nilValue, fmt.Errorf("failed to cast to int64 from empty array") + case reflect.Slice: + if v.Len() > 0 { + return castInt(v.Index(0)) + } + return nilValue, fmt.Errorf("failed to cast to int64 from empty slice") + case reflect.Interface: + return castInt(reflect.ValueOf(v.Interface())) + case reflect.Map: + return nilValue, fmt.Errorf("failed to cast to int64 from map") + case reflect.Struct: + return nilValue, fmt.Errorf("failed to cast to int64 from struct") + case reflect.Ptr: + return castInt(v.Elem()) + } + return nilValue, fmt.Errorf("failed to cast to int64 from %s", v.Type().Kind()) +} + +func castUint(v reflect.Value) (reflect.Value, error) { + switch v.Type().Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return reflect.ValueOf(uint64(v.Int())), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v, nil + case reflect.String: + u64, err := strconv.ParseUint(v.String(), 10, 64) + if err != nil { + return nilValue, err + } + return reflect.ValueOf(u64), nil + case reflect.Bool: + if v.Bool() { + return reflect.ValueOf(uint64(1)), nil + } + return reflect.ValueOf(uint64(0)), nil + case reflect.Float32, reflect.Float64: + return reflect.ValueOf(uint64(v.Float())), nil + case reflect.Array: + if v.Len() > 0 { + return castUint(v.Index(0)) + } + return nilValue, fmt.Errorf("failed to cast to uint64 from empty array") + case reflect.Slice: + if v.Len() > 0 { + return castUint(v.Index(0)) + } + return nilValue, fmt.Errorf("failed to cast to uint64 from empty slice") + case reflect.Interface: + return castUint(reflect.ValueOf(v.Interface())) + case reflect.Map: + return nilValue, fmt.Errorf("failed to cast to uint64 from map") + case reflect.Struct: + return nilValue, fmt.Errorf("failed to cast to uint64 from struct") + case reflect.Ptr: + return castUint(v.Elem()) + } + return nilValue, fmt.Errorf("failed to cast to uint64 from %s", v.Type().Kind()) +} + +func castString(v reflect.Value) (reflect.Value, error) { + switch v.Type().Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return reflect.ValueOf(fmt.Sprint(v.Int())), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return reflect.ValueOf(fmt.Sprint(v.Uint())), nil + case reflect.String: + return v, nil + case reflect.Bool: + if v.Bool() { + return reflect.ValueOf("true"), nil + } + return reflect.ValueOf("false"), nil + case reflect.Float32, reflect.Float64: + return reflect.ValueOf(fmt.Sprint(v.Float())), nil + case reflect.Array: + if v.Len() > 0 { + return castString(v.Index(0)) + } + return nilValue, fmt.Errorf("failed to cast to string from empty array") + case reflect.Slice: + if v.Len() > 0 { + return castString(v.Index(0)) + } + return nilValue, fmt.Errorf("failed to cast to string from empty slice") + case reflect.Interface: + return castString(reflect.ValueOf(v.Interface())) + case reflect.Map: + return nilValue, fmt.Errorf("failed to cast to string from map") + case reflect.Struct: + return nilValue, fmt.Errorf("failed to cast to string from struct") + case reflect.Ptr: + return castString(v.Elem()) + } + return nilValue, fmt.Errorf("failed to cast to string from %s", v.Type().Kind()) +} + +func castBool(v reflect.Value) (reflect.Value, error) { + switch v.Type().Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + switch v.Int() { + case 0: + return reflect.ValueOf(false), nil + case 1: + return reflect.ValueOf(true), nil + } + return nilValue, fmt.Errorf("failed to cast to bool from %d", v.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + switch v.Uint() { + case 0: + return reflect.ValueOf(false), nil + case 1: + return reflect.ValueOf(true), nil + } + return nilValue, fmt.Errorf("failed to cast to bool from %d", v.Uint()) + case reflect.String: + b, err := strconv.ParseBool(v.String()) + if err != nil { + return nilValue, err + } + return reflect.ValueOf(b), nil + case reflect.Bool: + return v, nil + case reflect.Float32, reflect.Float64: + switch v.Float() { + case 0: + return reflect.ValueOf(false), nil + case 1: + return reflect.ValueOf(true), nil + } + return nilValue, fmt.Errorf("failed to cast to bool from %f", v.Float()) + case reflect.Array: + if v.Len() > 0 { + return castBool(v.Index(0)) + } + return nilValue, fmt.Errorf("failed to cast to string from empty array") + case reflect.Slice: + if v.Len() > 0 { + return castBool(v.Index(0)) + } + return nilValue, fmt.Errorf("failed to cast to string from empty slice") + case reflect.Interface: + return castBool(reflect.ValueOf(v.Interface())) + case reflect.Map: + return nilValue, fmt.Errorf("failed to cast to string from map") + case reflect.Struct: + return nilValue, fmt.Errorf("failed to cast to string from struct") + case reflect.Ptr: + return castBool(v.Elem()) + } + return nilValue, fmt.Errorf("failed to cast to bool from %s", v.Type().Kind()) +} + +func castFloat(v reflect.Value) (reflect.Value, error) { + switch v.Type().Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return reflect.ValueOf(float64(v.Int())), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return reflect.ValueOf(float64(v.Uint())), nil + case reflect.String: + f64, err := strconv.ParseFloat(v.String(), 64) + if err != nil { + return nilValue, err + } + return reflect.ValueOf(f64), nil + case reflect.Bool: + if v.Bool() { + return reflect.ValueOf(float64(1)), nil + } + return reflect.ValueOf(float64(0)), nil + case reflect.Float32, reflect.Float64: + return v, nil + case reflect.Array: + if v.Len() > 0 { + return castFloat(v.Index(0)) + } + return nilValue, fmt.Errorf("failed to cast to float64 from empty array") + case reflect.Slice: + if v.Len() > 0 { + return castFloat(v.Index(0)) + } + return nilValue, fmt.Errorf("failed to cast to float64 from empty slice") + case reflect.Interface: + return castFloat(reflect.ValueOf(v.Interface())) + case reflect.Map: + return nilValue, fmt.Errorf("failed to cast to float64 from map") + case reflect.Struct: + return nilValue, fmt.Errorf("failed to cast to float64 from struct") + case reflect.Ptr: + return castFloat(v.Elem()) + } + return nilValue, fmt.Errorf("failed to cast to float64 from %s", v.Type().Kind()) +} + +func castArray(t reflect.Type, v reflect.Value) (reflect.Value, error) { + kind := v.Type().Kind() + if kind == reflect.Interface { + return castArray(t, reflect.ValueOf(v.Interface())) + } + if kind != reflect.Slice && kind != reflect.Array { + return nilValue, fmt.Errorf("failed to cast to array from %s", kind) + } + if t.Elem() == v.Type().Elem() { + return v, nil + } + if t.Len() != v.Len() { + return nilValue, fmt.Errorf("failed to cast [%d]array from slice of %d length", t.Len(), v.Len()) + } + ret := reflect.New(t).Elem() + for i := 0; i < v.Len(); i++ { + vv, err := castValue(t.Elem(), v.Index(i)) + if err != nil { + return nilValue, err + } + ret.Index(i).Set(vv) + } + return ret, nil +} + +func castSlice(t reflect.Type, v reflect.Value) (reflect.Value, error) { + kind := v.Type().Kind() + if kind == reflect.Interface { + return castSlice(t, reflect.ValueOf(v.Interface())) + } + if kind != reflect.Slice && kind != reflect.Array { + return nilValue, fmt.Errorf("failed to cast to slice from %s", kind) + } + if t.Elem() == v.Type().Elem() { + return v, nil + } + ret := reflect.MakeSlice(t, v.Len(), v.Len()) + for i := 0; i < v.Len(); i++ { + vv, err := castValue(t.Elem(), v.Index(i)) + if err != nil { + return nilValue, err + } + ret.Index(i).Set(vv) + } + return ret, nil +} + +func castMap(t reflect.Type, v reflect.Value) (reflect.Value, error) { + ret := reflect.MakeMap(t) + switch v.Type().Kind() { + case reflect.Map: + iter := v.MapRange() + for iter.Next() { + key, err := castValue(t.Key(), iter.Key()) + if err != nil { + return nilValue, err + } + value, err := castValue(t.Elem(), iter.Value()) + if err != nil { + return nilValue, err + } + ret.SetMapIndex(key, value) + } + return ret, nil + case reflect.Interface: + return castMap(t, reflect.ValueOf(v.Interface())) + case reflect.Slice: + if v.Len() > 0 { + return castMap(t, v.Index(0)) + } + return nilValue, fmt.Errorf("failed to cast to map from empty slice") + } + return nilValue, fmt.Errorf("failed to cast to map from %s", v.Type().Kind()) +} + +func castStruct(t reflect.Type, v reflect.Value) (reflect.Value, error) { + ret := reflect.New(t).Elem() + switch v.Type().Kind() { + case reflect.Map: + iter := v.MapRange() + for iter.Next() { + key := iter.Key() + k, err := castString(key) + if err != nil { + return nilValue, err + } + fieldName := k.String() + field, ok := t.FieldByName(fieldName) + if ok { + value, err := castValue(field.Type, iter.Value()) + if err != nil { + return nilValue, err + } + ret.FieldByName(fieldName).Set(value) + } + } + return ret, nil + case reflect.Struct: + for i := 0; i < v.Type().NumField(); i++ { + name := v.Type().Field(i).Name + ret.FieldByName(name).Set(v.FieldByName(name)) + } + return ret, nil + case reflect.Interface: + return castStruct(t, reflect.ValueOf(v.Interface())) + case reflect.Slice: + if v.Len() > 0 { + return castStruct(t, v.Index(0)) + } + return nilValue, fmt.Errorf("failed to cast to struct from empty slice") + default: + return nilValue, fmt.Errorf("failed to cast to struct from %s", v.Type().Kind()) + } +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/bool.go b/vendor/github.com/goccy/go-json/internal/decoder/bool.go new file mode 100644 index 000000000..ba6cf5bc4 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/bool.go @@ -0,0 +1,83 @@ +package decoder + +import ( + "fmt" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +type boolDecoder struct { + structName string + fieldName string +} + +func newBoolDecoder(structName, fieldName string) *boolDecoder { + return &boolDecoder{structName: structName, fieldName: fieldName} +} + +func (d *boolDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + c := s.skipWhiteSpace() + for { + switch c { + case 't': + if err := trueBytes(s); err != nil { + return err + } + **(**bool)(unsafe.Pointer(&p)) = true + return nil + case 'f': + if err := falseBytes(s); err != nil { + return err + } + **(**bool)(unsafe.Pointer(&p)) = false + return nil + case 'n': + if err := nullBytes(s); err != nil { + return err + } + return nil + case nul: + if s.read() { + c = s.char() + continue + } + goto ERROR + } + break + } +ERROR: + return errors.ErrUnexpectedEndOfJSON("bool", s.totalOffset()) +} + +func (d *boolDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + cursor = skipWhiteSpace(buf, cursor) + switch buf[cursor] { + case 't': + if err := validateTrue(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + **(**bool)(unsafe.Pointer(&p)) = true + return cursor, nil + case 'f': + if err := validateFalse(buf, cursor); err != nil { + return 0, err + } + cursor += 5 + **(**bool)(unsafe.Pointer(&p)) = false + return cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + return cursor, nil + } + return 0, errors.ErrUnexpectedEndOfJSON("bool", cursor) +} + +func (d *boolDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + return nil, 0, fmt.Errorf("json: bool decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/bytes.go b/vendor/github.com/goccy/go-json/internal/decoder/bytes.go new file mode 100644 index 000000000..939bf4327 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/bytes.go @@ -0,0 +1,118 @@ +package decoder + +import ( + "encoding/base64" + "fmt" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type bytesDecoder struct { + typ *runtime.Type + sliceDecoder Decoder + stringDecoder *stringDecoder + structName string + fieldName string +} + +func byteUnmarshalerSliceDecoder(typ *runtime.Type, structName string, fieldName string) Decoder { + var unmarshalDecoder Decoder + switch { + case runtime.PtrTo(typ).Implements(unmarshalJSONType): + unmarshalDecoder = newUnmarshalJSONDecoder(runtime.PtrTo(typ), structName, fieldName) + case runtime.PtrTo(typ).Implements(unmarshalTextType): + unmarshalDecoder = newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName) + default: + unmarshalDecoder, _ = compileUint8(typ, structName, fieldName) + } + return newSliceDecoder(unmarshalDecoder, typ, 1, structName, fieldName) +} + +func newBytesDecoder(typ *runtime.Type, structName string, fieldName string) *bytesDecoder { + return &bytesDecoder{ + typ: typ, + sliceDecoder: byteUnmarshalerSliceDecoder(typ, structName, fieldName), + stringDecoder: newStringDecoder(structName, fieldName), + structName: structName, + fieldName: fieldName, + } +} + +func (d *bytesDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + bytes, err := d.decodeStreamBinary(s, depth, p) + if err != nil { + return err + } + if bytes == nil { + s.reset() + return nil + } + decodedLen := base64.StdEncoding.DecodedLen(len(bytes)) + buf := make([]byte, decodedLen) + n, err := base64.StdEncoding.Decode(buf, bytes) + if err != nil { + return err + } + *(*[]byte)(p) = buf[:n] + s.reset() + return nil +} + +func (d *bytesDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + bytes, c, err := d.decodeBinary(ctx, cursor, depth, p) + if err != nil { + return 0, err + } + if bytes == nil { + return c, nil + } + cursor = c + decodedLen := base64.StdEncoding.DecodedLen(len(bytes)) + b := make([]byte, decodedLen) + n, err := base64.StdEncoding.Decode(b, bytes) + if err != nil { + return 0, err + } + *(*[]byte)(p) = b[:n] + return cursor, nil +} + +func (d *bytesDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + return nil, 0, fmt.Errorf("json: []byte decoder does not support decode path") +} + +func (d *bytesDecoder) decodeStreamBinary(s *Stream, depth int64, p unsafe.Pointer) ([]byte, error) { + c := s.skipWhiteSpace() + if c == '[' { + if d.sliceDecoder == nil { + return nil, &errors.UnmarshalTypeError{ + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + } + err := d.sliceDecoder.DecodeStream(s, depth, p) + return nil, err + } + return d.stringDecoder.decodeStreamByte(s) +} + +func (d *bytesDecoder) decodeBinary(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) ([]byte, int64, error) { + buf := ctx.Buf + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == '[' { + if d.sliceDecoder == nil { + return nil, 0, &errors.UnmarshalTypeError{ + Type: runtime.RType2Type(d.typ), + Offset: cursor, + } + } + c, err := d.sliceDecoder.Decode(ctx, cursor, depth, p) + if err != nil { + return nil, 0, err + } + return nil, c, nil + } + return d.stringDecoder.decodeByte(buf, cursor) +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/compile.go b/vendor/github.com/goccy/go-json/internal/decoder/compile.go new file mode 100644 index 000000000..fab643764 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/compile.go @@ -0,0 +1,487 @@ +package decoder + +import ( + "encoding/json" + "fmt" + "reflect" + "strings" + "sync/atomic" + "unicode" + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +var ( + jsonNumberType = reflect.TypeOf(json.Number("")) + typeAddr *runtime.TypeAddr + cachedDecoderMap unsafe.Pointer // map[uintptr]decoder + cachedDecoder []Decoder +) + +func init() { + typeAddr = runtime.AnalyzeTypeAddr() + if typeAddr == nil { + typeAddr = &runtime.TypeAddr{} + } + cachedDecoder = make([]Decoder, typeAddr.AddrRange>>typeAddr.AddrShift+1) +} + +func loadDecoderMap() map[uintptr]Decoder { + p := atomic.LoadPointer(&cachedDecoderMap) + return *(*map[uintptr]Decoder)(unsafe.Pointer(&p)) +} + +func storeDecoder(typ uintptr, dec Decoder, m map[uintptr]Decoder) { + newDecoderMap := make(map[uintptr]Decoder, len(m)+1) + newDecoderMap[typ] = dec + + for k, v := range m { + newDecoderMap[k] = v + } + + atomic.StorePointer(&cachedDecoderMap, *(*unsafe.Pointer)(unsafe.Pointer(&newDecoderMap))) +} + +func compileToGetDecoderSlowPath(typeptr uintptr, typ *runtime.Type) (Decoder, error) { + decoderMap := loadDecoderMap() + if dec, exists := decoderMap[typeptr]; exists { + return dec, nil + } + + dec, err := compileHead(typ, map[uintptr]Decoder{}) + if err != nil { + return nil, err + } + storeDecoder(typeptr, dec, decoderMap) + return dec, nil +} + +func compileHead(typ *runtime.Type, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + switch { + case implementsUnmarshalJSONType(runtime.PtrTo(typ)): + return newUnmarshalJSONDecoder(runtime.PtrTo(typ), "", ""), nil + case runtime.PtrTo(typ).Implements(unmarshalTextType): + return newUnmarshalTextDecoder(runtime.PtrTo(typ), "", ""), nil + } + return compile(typ.Elem(), "", "", structTypeToDecoder) +} + +func compile(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + switch { + case implementsUnmarshalJSONType(runtime.PtrTo(typ)): + return newUnmarshalJSONDecoder(runtime.PtrTo(typ), structName, fieldName), nil + case runtime.PtrTo(typ).Implements(unmarshalTextType): + return newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName), nil + } + + switch typ.Kind() { + case reflect.Ptr: + return compilePtr(typ, structName, fieldName, structTypeToDecoder) + case reflect.Struct: + return compileStruct(typ, structName, fieldName, structTypeToDecoder) + case reflect.Slice: + elem := typ.Elem() + if elem.Kind() == reflect.Uint8 { + return compileBytes(elem, structName, fieldName) + } + return compileSlice(typ, structName, fieldName, structTypeToDecoder) + case reflect.Array: + return compileArray(typ, structName, fieldName, structTypeToDecoder) + case reflect.Map: + return compileMap(typ, structName, fieldName, structTypeToDecoder) + case reflect.Interface: + return compileInterface(typ, structName, fieldName) + case reflect.Uintptr: + return compileUint(typ, structName, fieldName) + case reflect.Int: + return compileInt(typ, structName, fieldName) + case reflect.Int8: + return compileInt8(typ, structName, fieldName) + case reflect.Int16: + return compileInt16(typ, structName, fieldName) + case reflect.Int32: + return compileInt32(typ, structName, fieldName) + case reflect.Int64: + return compileInt64(typ, structName, fieldName) + case reflect.Uint: + return compileUint(typ, structName, fieldName) + case reflect.Uint8: + return compileUint8(typ, structName, fieldName) + case reflect.Uint16: + return compileUint16(typ, structName, fieldName) + case reflect.Uint32: + return compileUint32(typ, structName, fieldName) + case reflect.Uint64: + return compileUint64(typ, structName, fieldName) + case reflect.String: + return compileString(typ, structName, fieldName) + case reflect.Bool: + return compileBool(structName, fieldName) + case reflect.Float32: + return compileFloat32(structName, fieldName) + case reflect.Float64: + return compileFloat64(structName, fieldName) + case reflect.Func: + return compileFunc(typ, structName, fieldName) + } + return newInvalidDecoder(typ, structName, fieldName), nil +} + +func isStringTagSupportedType(typ *runtime.Type) bool { + switch { + case implementsUnmarshalJSONType(runtime.PtrTo(typ)): + return false + case runtime.PtrTo(typ).Implements(unmarshalTextType): + return false + } + switch typ.Kind() { + case reflect.Map: + return false + case reflect.Slice: + return false + case reflect.Array: + return false + case reflect.Struct: + return false + case reflect.Interface: + return false + } + return true +} + +func compileMapKey(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + if runtime.PtrTo(typ).Implements(unmarshalTextType) { + return newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName), nil + } + if typ.Kind() == reflect.String { + return newStringDecoder(structName, fieldName), nil + } + dec, err := compile(typ, structName, fieldName, structTypeToDecoder) + if err != nil { + return nil, err + } + for { + switch t := dec.(type) { + case *stringDecoder, *interfaceDecoder: + return dec, nil + case *boolDecoder, *intDecoder, *uintDecoder, *numberDecoder: + return newWrappedStringDecoder(typ, dec, structName, fieldName), nil + case *ptrDecoder: + dec = t.dec + default: + return newInvalidDecoder(typ, structName, fieldName), nil + } + } +} + +func compilePtr(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + dec, err := compile(typ.Elem(), structName, fieldName, structTypeToDecoder) + if err != nil { + return nil, err + } + return newPtrDecoder(dec, typ.Elem(), structName, fieldName), nil +} + +func compileInt(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { + *(*int)(p) = int(v) + }), nil +} + +func compileInt8(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { + *(*int8)(p) = int8(v) + }), nil +} + +func compileInt16(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { + *(*int16)(p) = int16(v) + }), nil +} + +func compileInt32(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { + *(*int32)(p) = int32(v) + }), nil +} + +func compileInt64(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { + *(*int64)(p) = v + }), nil +} + +func compileUint(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { + *(*uint)(p) = uint(v) + }), nil +} + +func compileUint8(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { + *(*uint8)(p) = uint8(v) + }), nil +} + +func compileUint16(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { + *(*uint16)(p) = uint16(v) + }), nil +} + +func compileUint32(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { + *(*uint32)(p) = uint32(v) + }), nil +} + +func compileUint64(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { + *(*uint64)(p) = v + }), nil +} + +func compileFloat32(structName, fieldName string) (Decoder, error) { + return newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) { + *(*float32)(p) = float32(v) + }), nil +} + +func compileFloat64(structName, fieldName string) (Decoder, error) { + return newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) { + *(*float64)(p) = v + }), nil +} + +func compileString(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + if typ == runtime.Type2RType(jsonNumberType) { + return newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) { + *(*json.Number)(p) = v + }), nil + } + return newStringDecoder(structName, fieldName), nil +} + +func compileBool(structName, fieldName string) (Decoder, error) { + return newBoolDecoder(structName, fieldName), nil +} + +func compileBytes(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newBytesDecoder(typ, structName, fieldName), nil +} + +func compileSlice(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + elem := typ.Elem() + decoder, err := compile(elem, structName, fieldName, structTypeToDecoder) + if err != nil { + return nil, err + } + return newSliceDecoder(decoder, elem, elem.Size(), structName, fieldName), nil +} + +func compileArray(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + elem := typ.Elem() + decoder, err := compile(elem, structName, fieldName, structTypeToDecoder) + if err != nil { + return nil, err + } + return newArrayDecoder(decoder, elem, typ.Len(), structName, fieldName), nil +} + +func compileMap(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + keyDec, err := compileMapKey(typ.Key(), structName, fieldName, structTypeToDecoder) + if err != nil { + return nil, err + } + valueDec, err := compile(typ.Elem(), structName, fieldName, structTypeToDecoder) + if err != nil { + return nil, err + } + return newMapDecoder(typ, typ.Key(), keyDec, typ.Elem(), valueDec, structName, fieldName), nil +} + +func compileInterface(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newInterfaceDecoder(typ, structName, fieldName), nil +} + +func compileFunc(typ *runtime.Type, strutName, fieldName string) (Decoder, error) { + return newFuncDecoder(typ, strutName, fieldName), nil +} + +func typeToStructTags(typ *runtime.Type) runtime.StructTags { + tags := runtime.StructTags{} + fieldNum := typ.NumField() + for i := 0; i < fieldNum; i++ { + field := typ.Field(i) + if runtime.IsIgnoredStructField(field) { + continue + } + tags = append(tags, runtime.StructTagFromField(field)) + } + return tags +} + +func compileStruct(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + fieldNum := typ.NumField() + fieldMap := map[string]*structFieldSet{} + typeptr := uintptr(unsafe.Pointer(typ)) + if dec, exists := structTypeToDecoder[typeptr]; exists { + return dec, nil + } + structDec := newStructDecoder(structName, fieldName, fieldMap) + structTypeToDecoder[typeptr] = structDec + structName = typ.Name() + tags := typeToStructTags(typ) + allFields := []*structFieldSet{} + for i := 0; i < fieldNum; i++ { + field := typ.Field(i) + if runtime.IsIgnoredStructField(field) { + continue + } + isUnexportedField := unicode.IsLower([]rune(field.Name)[0]) + tag := runtime.StructTagFromField(field) + dec, err := compile(runtime.Type2RType(field.Type), structName, field.Name, structTypeToDecoder) + if err != nil { + return nil, err + } + if field.Anonymous && !tag.IsTaggedKey { + if stDec, ok := dec.(*structDecoder); ok { + if runtime.Type2RType(field.Type) == typ { + // recursive definition + continue + } + for k, v := range stDec.fieldMap { + if tags.ExistsKey(k) { + continue + } + fieldSet := &structFieldSet{ + dec: v.dec, + offset: field.Offset + v.offset, + isTaggedKey: v.isTaggedKey, + key: k, + keyLen: int64(len(k)), + } + allFields = append(allFields, fieldSet) + } + } else if pdec, ok := dec.(*ptrDecoder); ok { + contentDec := pdec.contentDecoder() + if pdec.typ == typ { + // recursive definition + continue + } + var fieldSetErr error + if isUnexportedField { + fieldSetErr = fmt.Errorf( + "json: cannot set embedded pointer to unexported struct: %v", + field.Type.Elem(), + ) + } + if dec, ok := contentDec.(*structDecoder); ok { + for k, v := range dec.fieldMap { + if tags.ExistsKey(k) { + continue + } + fieldSet := &structFieldSet{ + dec: newAnonymousFieldDecoder(pdec.typ, v.offset, v.dec), + offset: field.Offset, + isTaggedKey: v.isTaggedKey, + key: k, + keyLen: int64(len(k)), + err: fieldSetErr, + } + allFields = append(allFields, fieldSet) + } + } else { + fieldSet := &structFieldSet{ + dec: pdec, + offset: field.Offset, + isTaggedKey: tag.IsTaggedKey, + key: field.Name, + keyLen: int64(len(field.Name)), + } + allFields = append(allFields, fieldSet) + } + } else { + fieldSet := &structFieldSet{ + dec: dec, + offset: field.Offset, + isTaggedKey: tag.IsTaggedKey, + key: field.Name, + keyLen: int64(len(field.Name)), + } + allFields = append(allFields, fieldSet) + } + } else { + if tag.IsString && isStringTagSupportedType(runtime.Type2RType(field.Type)) { + dec = newWrappedStringDecoder(runtime.Type2RType(field.Type), dec, structName, field.Name) + } + var key string + if tag.Key != "" { + key = tag.Key + } else { + key = field.Name + } + fieldSet := &structFieldSet{ + dec: dec, + offset: field.Offset, + isTaggedKey: tag.IsTaggedKey, + key: key, + keyLen: int64(len(key)), + } + allFields = append(allFields, fieldSet) + } + } + for _, set := range filterDuplicatedFields(allFields) { + fieldMap[set.key] = set + lower := strings.ToLower(set.key) + if _, exists := fieldMap[lower]; !exists { + // first win + fieldMap[lower] = set + } + } + delete(structTypeToDecoder, typeptr) + structDec.tryOptimize() + return structDec, nil +} + +func filterDuplicatedFields(allFields []*structFieldSet) []*structFieldSet { + fieldMap := map[string][]*structFieldSet{} + for _, field := range allFields { + fieldMap[field.key] = append(fieldMap[field.key], field) + } + duplicatedFieldMap := map[string]struct{}{} + for k, sets := range fieldMap { + sets = filterFieldSets(sets) + if len(sets) != 1 { + duplicatedFieldMap[k] = struct{}{} + } + } + + filtered := make([]*structFieldSet, 0, len(allFields)) + for _, field := range allFields { + if _, exists := duplicatedFieldMap[field.key]; exists { + continue + } + filtered = append(filtered, field) + } + return filtered +} + +func filterFieldSets(sets []*structFieldSet) []*structFieldSet { + if len(sets) == 1 { + return sets + } + filtered := make([]*structFieldSet, 0, len(sets)) + for _, set := range sets { + if set.isTaggedKey { + filtered = append(filtered, set) + } + } + return filtered +} + +func implementsUnmarshalJSONType(typ *runtime.Type) bool { + return typ.Implements(unmarshalJSONType) || typ.Implements(unmarshalJSONContextType) +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go b/vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go new file mode 100644 index 000000000..eb7e2b134 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go @@ -0,0 +1,29 @@ +//go:build !race +// +build !race + +package decoder + +import ( + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +func CompileToGetDecoder(typ *runtime.Type) (Decoder, error) { + typeptr := uintptr(unsafe.Pointer(typ)) + if typeptr > typeAddr.MaxTypeAddr { + return compileToGetDecoderSlowPath(typeptr, typ) + } + + index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift + if dec := cachedDecoder[index]; dec != nil { + return dec, nil + } + + dec, err := compileHead(typ, map[uintptr]Decoder{}) + if err != nil { + return nil, err + } + cachedDecoder[index] = dec + return dec, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/compile_race.go b/vendor/github.com/goccy/go-json/internal/decoder/compile_race.go new file mode 100644 index 000000000..49cdda4a1 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/compile_race.go @@ -0,0 +1,37 @@ +//go:build race +// +build race + +package decoder + +import ( + "sync" + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +var decMu sync.RWMutex + +func CompileToGetDecoder(typ *runtime.Type) (Decoder, error) { + typeptr := uintptr(unsafe.Pointer(typ)) + if typeptr > typeAddr.MaxTypeAddr { + return compileToGetDecoderSlowPath(typeptr, typ) + } + + index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift + decMu.RLock() + if dec := cachedDecoder[index]; dec != nil { + decMu.RUnlock() + return dec, nil + } + decMu.RUnlock() + + dec, err := compileHead(typ, map[uintptr]Decoder{}) + if err != nil { + return nil, err + } + decMu.Lock() + cachedDecoder[index] = dec + decMu.Unlock() + return dec, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/context.go b/vendor/github.com/goccy/go-json/internal/decoder/context.go new file mode 100644 index 000000000..cb2ffdafd --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/context.go @@ -0,0 +1,254 @@ +package decoder + +import ( + "sync" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +type RuntimeContext struct { + Buf []byte + Option *Option +} + +var ( + runtimeContextPool = sync.Pool{ + New: func() interface{} { + return &RuntimeContext{ + Option: &Option{}, + } + }, + } +) + +func TakeRuntimeContext() *RuntimeContext { + return runtimeContextPool.Get().(*RuntimeContext) +} + +func ReleaseRuntimeContext(ctx *RuntimeContext) { + runtimeContextPool.Put(ctx) +} + +var ( + isWhiteSpace = [256]bool{} +) + +func init() { + isWhiteSpace[' '] = true + isWhiteSpace['\n'] = true + isWhiteSpace['\t'] = true + isWhiteSpace['\r'] = true +} + +func char(ptr unsafe.Pointer, offset int64) byte { + return *(*byte)(unsafe.Pointer(uintptr(ptr) + uintptr(offset))) +} + +func skipWhiteSpace(buf []byte, cursor int64) int64 { + for isWhiteSpace[buf[cursor]] { + cursor++ + } + return cursor +} + +func skipObject(buf []byte, cursor, depth int64) (int64, error) { + braceCount := 1 + for { + switch buf[cursor] { + case '{': + braceCount++ + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + case '}': + depth-- + braceCount-- + if braceCount == 0 { + return cursor + 1, nil + } + case '[': + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + case ']': + depth-- + case '"': + for { + cursor++ + switch buf[cursor] { + case '\\': + cursor++ + if buf[cursor] == nul { + return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + case '"': + goto SWITCH_OUT + case nul: + return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + } + case nul: + return 0, errors.ErrUnexpectedEndOfJSON("object of object", cursor) + } + SWITCH_OUT: + cursor++ + } +} + +func skipArray(buf []byte, cursor, depth int64) (int64, error) { + bracketCount := 1 + for { + switch buf[cursor] { + case '[': + bracketCount++ + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + case ']': + bracketCount-- + depth-- + if bracketCount == 0 { + return cursor + 1, nil + } + case '{': + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + case '}': + depth-- + case '"': + for { + cursor++ + switch buf[cursor] { + case '\\': + cursor++ + if buf[cursor] == nul { + return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + case '"': + goto SWITCH_OUT + case nul: + return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + } + case nul: + return 0, errors.ErrUnexpectedEndOfJSON("array of object", cursor) + } + SWITCH_OUT: + cursor++ + } +} + +func skipValue(buf []byte, cursor, depth int64) (int64, error) { + for { + switch buf[cursor] { + case ' ', '\t', '\n', '\r': + cursor++ + continue + case '{': + return skipObject(buf, cursor+1, depth+1) + case '[': + return skipArray(buf, cursor+1, depth+1) + case '"': + for { + cursor++ + switch buf[cursor] { + case '\\': + cursor++ + if buf[cursor] == nul { + return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + case '"': + return cursor + 1, nil + case nul: + return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + for { + cursor++ + if floatTable[buf[cursor]] { + continue + } + break + } + return cursor, nil + case 't': + if err := validateTrue(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + return cursor, nil + case 'f': + if err := validateFalse(buf, cursor); err != nil { + return 0, err + } + cursor += 5 + return cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + return cursor, nil + default: + return cursor, errors.ErrUnexpectedEndOfJSON("null", cursor) + } + } +} + +func validateTrue(buf []byte, cursor int64) error { + if cursor+3 >= int64(len(buf)) { + return errors.ErrUnexpectedEndOfJSON("true", cursor) + } + if buf[cursor+1] != 'r' { + return errors.ErrInvalidCharacter(buf[cursor+1], "true", cursor) + } + if buf[cursor+2] != 'u' { + return errors.ErrInvalidCharacter(buf[cursor+2], "true", cursor) + } + if buf[cursor+3] != 'e' { + return errors.ErrInvalidCharacter(buf[cursor+3], "true", cursor) + } + return nil +} + +func validateFalse(buf []byte, cursor int64) error { + if cursor+4 >= int64(len(buf)) { + return errors.ErrUnexpectedEndOfJSON("false", cursor) + } + if buf[cursor+1] != 'a' { + return errors.ErrInvalidCharacter(buf[cursor+1], "false", cursor) + } + if buf[cursor+2] != 'l' { + return errors.ErrInvalidCharacter(buf[cursor+2], "false", cursor) + } + if buf[cursor+3] != 's' { + return errors.ErrInvalidCharacter(buf[cursor+3], "false", cursor) + } + if buf[cursor+4] != 'e' { + return errors.ErrInvalidCharacter(buf[cursor+4], "false", cursor) + } + return nil +} + +func validateNull(buf []byte, cursor int64) error { + if cursor+3 >= int64(len(buf)) { + return errors.ErrUnexpectedEndOfJSON("null", cursor) + } + if buf[cursor+1] != 'u' { + return errors.ErrInvalidCharacter(buf[cursor+1], "null", cursor) + } + if buf[cursor+2] != 'l' { + return errors.ErrInvalidCharacter(buf[cursor+2], "null", cursor) + } + if buf[cursor+3] != 'l' { + return errors.ErrInvalidCharacter(buf[cursor+3], "null", cursor) + } + return nil +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/float.go b/vendor/github.com/goccy/go-json/internal/decoder/float.go new file mode 100644 index 000000000..9b2eb8b35 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/float.go @@ -0,0 +1,170 @@ +package decoder + +import ( + "strconv" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +type floatDecoder struct { + op func(unsafe.Pointer, float64) + structName string + fieldName string +} + +func newFloatDecoder(structName, fieldName string, op func(unsafe.Pointer, float64)) *floatDecoder { + return &floatDecoder{op: op, structName: structName, fieldName: fieldName} +} + +var ( + floatTable = [256]bool{ + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + '.': true, + 'e': true, + 'E': true, + '+': true, + '-': true, + } + + validEndNumberChar = [256]bool{ + nul: true, + ' ': true, + '\t': true, + '\r': true, + '\n': true, + ',': true, + ':': true, + '}': true, + ']': true, + } +) + +func floatBytes(s *Stream) []byte { + start := s.cursor + for { + s.cursor++ + if floatTable[s.char()] { + continue + } else if s.char() == nul { + if s.read() { + s.cursor-- // for retry current character + continue + } + } + break + } + return s.buf[start:s.cursor] +} + +func (d *floatDecoder) decodeStreamByte(s *Stream) ([]byte, error) { + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + s.cursor++ + continue + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return floatBytes(s), nil + case 'n': + if err := nullBytes(s); err != nil { + return nil, err + } + return nil, nil + case nul: + if s.read() { + continue + } + goto ERROR + default: + goto ERROR + } + } +ERROR: + return nil, errors.ErrUnexpectedEndOfJSON("float", s.totalOffset()) +} + +func (d *floatDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) { + for { + switch buf[cursor] { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + start := cursor + cursor++ + for floatTable[buf[cursor]] { + cursor++ + } + num := buf[start:cursor] + return num, cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return nil, cursor, nil + default: + return nil, 0, errors.ErrUnexpectedEndOfJSON("float", cursor) + } + } +} + +func (d *floatDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + bytes, err := d.decodeStreamByte(s) + if err != nil { + return err + } + if bytes == nil { + return nil + } + str := *(*string)(unsafe.Pointer(&bytes)) + f64, err := strconv.ParseFloat(str, 64) + if err != nil { + return errors.ErrSyntax(err.Error(), s.totalOffset()) + } + d.op(p, f64) + return nil +} + +func (d *floatDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + bytes, c, err := d.decodeByte(buf, cursor) + if err != nil { + return 0, err + } + if bytes == nil { + return c, nil + } + cursor = c + if !validEndNumberChar[buf[cursor]] { + return 0, errors.ErrUnexpectedEndOfJSON("float", cursor) + } + s := *(*string)(unsafe.Pointer(&bytes)) + f64, err := strconv.ParseFloat(s, 64) + if err != nil { + return 0, errors.ErrSyntax(err.Error(), cursor) + } + d.op(p, f64) + return cursor, nil +} + +func (d *floatDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + buf := ctx.Buf + bytes, c, err := d.decodeByte(buf, cursor) + if err != nil { + return nil, 0, err + } + if bytes == nil { + return [][]byte{nullbytes}, c, nil + } + return [][]byte{bytes}, c, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/func.go b/vendor/github.com/goccy/go-json/internal/decoder/func.go new file mode 100644 index 000000000..4cc12ca81 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/func.go @@ -0,0 +1,146 @@ +package decoder + +import ( + "bytes" + "fmt" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type funcDecoder struct { + typ *runtime.Type + structName string + fieldName string +} + +func newFuncDecoder(typ *runtime.Type, structName, fieldName string) *funcDecoder { + fnDecoder := &funcDecoder{typ, structName, fieldName} + return fnDecoder +} + +func (d *funcDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + s.skipWhiteSpace() + start := s.cursor + if err := s.skipValue(depth); err != nil { + return err + } + src := s.buf[start:s.cursor] + if len(src) > 0 { + switch src[0] { + case '"': + return &errors.UnmarshalTypeError{ + Value: "string", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + case '[': + return &errors.UnmarshalTypeError{ + Value: "array", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + case '{': + return &errors.UnmarshalTypeError{ + Value: "object", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return &errors.UnmarshalTypeError{ + Value: "number", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + case 'n': + if err := nullBytes(s); err != nil { + return err + } + *(*unsafe.Pointer)(p) = nil + return nil + case 't': + if err := trueBytes(s); err == nil { + return &errors.UnmarshalTypeError{ + Value: "boolean", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + } + case 'f': + if err := falseBytes(s); err == nil { + return &errors.UnmarshalTypeError{ + Value: "boolean", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + } + } + } + return errors.ErrInvalidBeginningOfValue(s.buf[s.cursor], s.totalOffset()) +} + +func (d *funcDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + cursor = skipWhiteSpace(buf, cursor) + start := cursor + end, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + src := buf[start:end] + if len(src) > 0 { + switch src[0] { + case '"': + return 0, &errors.UnmarshalTypeError{ + Value: "string", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + case '[': + return 0, &errors.UnmarshalTypeError{ + Value: "array", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + case '{': + return 0, &errors.UnmarshalTypeError{ + Value: "object", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return 0, &errors.UnmarshalTypeError{ + Value: "number", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + case 'n': + if bytes.Equal(src, nullbytes) { + *(*unsafe.Pointer)(p) = nil + return end, nil + } + case 't': + if err := validateTrue(buf, start); err == nil { + return 0, &errors.UnmarshalTypeError{ + Value: "boolean", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + } + case 'f': + if err := validateFalse(buf, start); err == nil { + return 0, &errors.UnmarshalTypeError{ + Value: "boolean", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + } + } + } + return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor) +} + +func (d *funcDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + return nil, 0, fmt.Errorf("json: func decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/int.go b/vendor/github.com/goccy/go-json/internal/decoder/int.go new file mode 100644 index 000000000..1a7f08199 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/int.go @@ -0,0 +1,246 @@ +package decoder + +import ( + "fmt" + "reflect" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type intDecoder struct { + typ *runtime.Type + kind reflect.Kind + op func(unsafe.Pointer, int64) + structName string + fieldName string +} + +func newIntDecoder(typ *runtime.Type, structName, fieldName string, op func(unsafe.Pointer, int64)) *intDecoder { + return &intDecoder{ + typ: typ, + kind: typ.Kind(), + op: op, + structName: structName, + fieldName: fieldName, + } +} + +func (d *intDecoder) typeError(buf []byte, offset int64) *errors.UnmarshalTypeError { + return &errors.UnmarshalTypeError{ + Value: fmt.Sprintf("number %s", string(buf)), + Type: runtime.RType2Type(d.typ), + Struct: d.structName, + Field: d.fieldName, + Offset: offset, + } +} + +var ( + pow10i64 = [...]int64{ + 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, + } + pow10i64Len = len(pow10i64) +) + +func (d *intDecoder) parseInt(b []byte) (int64, error) { + isNegative := false + if b[0] == '-' { + b = b[1:] + isNegative = true + } + maxDigit := len(b) + if maxDigit > pow10i64Len { + return 0, fmt.Errorf("invalid length of number") + } + sum := int64(0) + for i := 0; i < maxDigit; i++ { + c := int64(b[i]) - 48 + digitValue := pow10i64[maxDigit-i-1] + sum += c * digitValue + } + if isNegative { + return -1 * sum, nil + } + return sum, nil +} + +var ( + numTable = [256]bool{ + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + } +) + +var ( + numZeroBuf = []byte{'0'} +) + +func (d *intDecoder) decodeStreamByte(s *Stream) ([]byte, error) { + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + s.cursor++ + continue + case '-': + start := s.cursor + for { + s.cursor++ + if numTable[s.char()] { + continue + } else if s.char() == nul { + if s.read() { + s.cursor-- // for retry current character + continue + } + } + break + } + num := s.buf[start:s.cursor] + if len(num) < 2 { + goto ERROR + } + return num, nil + case '0': + s.cursor++ + return numZeroBuf, nil + case '1', '2', '3', '4', '5', '6', '7', '8', '9': + start := s.cursor + for { + s.cursor++ + if numTable[s.char()] { + continue + } else if s.char() == nul { + if s.read() { + s.cursor-- // for retry current character + continue + } + } + break + } + num := s.buf[start:s.cursor] + return num, nil + case 'n': + if err := nullBytes(s); err != nil { + return nil, err + } + return nil, nil + case nul: + if s.read() { + continue + } + goto ERROR + default: + return nil, d.typeError([]byte{s.char()}, s.totalOffset()) + } + } +ERROR: + return nil, errors.ErrUnexpectedEndOfJSON("number(integer)", s.totalOffset()) +} + +func (d *intDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) { + b := (*sliceHeader)(unsafe.Pointer(&buf)).data + for { + switch char(b, cursor) { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case '0': + cursor++ + return numZeroBuf, cursor, nil + case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9': + start := cursor + cursor++ + for numTable[char(b, cursor)] { + cursor++ + } + num := buf[start:cursor] + return num, cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return nil, cursor, nil + default: + return nil, 0, d.typeError([]byte{char(b, cursor)}, cursor) + } + } +} + +func (d *intDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + bytes, err := d.decodeStreamByte(s) + if err != nil { + return err + } + if bytes == nil { + return nil + } + i64, err := d.parseInt(bytes) + if err != nil { + return d.typeError(bytes, s.totalOffset()) + } + switch d.kind { + case reflect.Int8: + if i64 < -1*(1<<7) || (1<<7) <= i64 { + return d.typeError(bytes, s.totalOffset()) + } + case reflect.Int16: + if i64 < -1*(1<<15) || (1<<15) <= i64 { + return d.typeError(bytes, s.totalOffset()) + } + case reflect.Int32: + if i64 < -1*(1<<31) || (1<<31) <= i64 { + return d.typeError(bytes, s.totalOffset()) + } + } + d.op(p, i64) + s.reset() + return nil +} + +func (d *intDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + bytes, c, err := d.decodeByte(ctx.Buf, cursor) + if err != nil { + return 0, err + } + if bytes == nil { + return c, nil + } + cursor = c + + i64, err := d.parseInt(bytes) + if err != nil { + return 0, d.typeError(bytes, cursor) + } + switch d.kind { + case reflect.Int8: + if i64 < -1*(1<<7) || (1<<7) <= i64 { + return 0, d.typeError(bytes, cursor) + } + case reflect.Int16: + if i64 < -1*(1<<15) || (1<<15) <= i64 { + return 0, d.typeError(bytes, cursor) + } + case reflect.Int32: + if i64 < -1*(1<<31) || (1<<31) <= i64 { + return 0, d.typeError(bytes, cursor) + } + } + d.op(p, i64) + return cursor, nil +} + +func (d *intDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + return nil, 0, fmt.Errorf("json: int decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/interface.go b/vendor/github.com/goccy/go-json/internal/decoder/interface.go new file mode 100644 index 000000000..45c69ab8c --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/interface.go @@ -0,0 +1,528 @@ +package decoder + +import ( + "bytes" + "encoding" + "encoding/json" + "reflect" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type interfaceDecoder struct { + typ *runtime.Type + structName string + fieldName string + sliceDecoder *sliceDecoder + mapDecoder *mapDecoder + floatDecoder *floatDecoder + numberDecoder *numberDecoder + stringDecoder *stringDecoder +} + +func newEmptyInterfaceDecoder(structName, fieldName string) *interfaceDecoder { + ifaceDecoder := &interfaceDecoder{ + typ: emptyInterfaceType, + structName: structName, + fieldName: fieldName, + floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) { + *(*interface{})(p) = v + }), + numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) { + *(*interface{})(p) = v + }), + stringDecoder: newStringDecoder(structName, fieldName), + } + ifaceDecoder.sliceDecoder = newSliceDecoder( + ifaceDecoder, + emptyInterfaceType, + emptyInterfaceType.Size(), + structName, fieldName, + ) + ifaceDecoder.mapDecoder = newMapDecoder( + interfaceMapType, + stringType, + ifaceDecoder.stringDecoder, + interfaceMapType.Elem(), + ifaceDecoder, + structName, + fieldName, + ) + return ifaceDecoder +} + +func newInterfaceDecoder(typ *runtime.Type, structName, fieldName string) *interfaceDecoder { + emptyIfaceDecoder := newEmptyInterfaceDecoder(structName, fieldName) + stringDecoder := newStringDecoder(structName, fieldName) + return &interfaceDecoder{ + typ: typ, + structName: structName, + fieldName: fieldName, + sliceDecoder: newSliceDecoder( + emptyIfaceDecoder, + emptyInterfaceType, + emptyInterfaceType.Size(), + structName, fieldName, + ), + mapDecoder: newMapDecoder( + interfaceMapType, + stringType, + stringDecoder, + interfaceMapType.Elem(), + emptyIfaceDecoder, + structName, + fieldName, + ), + floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) { + *(*interface{})(p) = v + }), + numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) { + *(*interface{})(p) = v + }), + stringDecoder: stringDecoder, + } +} + +func (d *interfaceDecoder) numDecoder(s *Stream) Decoder { + if s.UseNumber { + return d.numberDecoder + } + return d.floatDecoder +} + +var ( + emptyInterfaceType = runtime.Type2RType(reflect.TypeOf((*interface{})(nil)).Elem()) + EmptyInterfaceType = emptyInterfaceType + interfaceMapType = runtime.Type2RType( + reflect.TypeOf((*map[string]interface{})(nil)).Elem(), + ) + stringType = runtime.Type2RType( + reflect.TypeOf(""), + ) +) + +func decodeStreamUnmarshaler(s *Stream, depth int64, unmarshaler json.Unmarshaler) error { + start := s.cursor + if err := s.skipValue(depth); err != nil { + return err + } + src := s.buf[start:s.cursor] + dst := make([]byte, len(src)) + copy(dst, src) + + if err := unmarshaler.UnmarshalJSON(dst); err != nil { + return err + } + return nil +} + +func decodeStreamUnmarshalerContext(s *Stream, depth int64, unmarshaler unmarshalerContext) error { + start := s.cursor + if err := s.skipValue(depth); err != nil { + return err + } + src := s.buf[start:s.cursor] + dst := make([]byte, len(src)) + copy(dst, src) + + if err := unmarshaler.UnmarshalJSON(s.Option.Context, dst); err != nil { + return err + } + return nil +} + +func decodeUnmarshaler(buf []byte, cursor, depth int64, unmarshaler json.Unmarshaler) (int64, error) { + cursor = skipWhiteSpace(buf, cursor) + start := cursor + end, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + src := buf[start:end] + dst := make([]byte, len(src)) + copy(dst, src) + + if err := unmarshaler.UnmarshalJSON(dst); err != nil { + return 0, err + } + return end, nil +} + +func decodeUnmarshalerContext(ctx *RuntimeContext, buf []byte, cursor, depth int64, unmarshaler unmarshalerContext) (int64, error) { + cursor = skipWhiteSpace(buf, cursor) + start := cursor + end, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + src := buf[start:end] + dst := make([]byte, len(src)) + copy(dst, src) + + if err := unmarshaler.UnmarshalJSON(ctx.Option.Context, dst); err != nil { + return 0, err + } + return end, nil +} + +func decodeStreamTextUnmarshaler(s *Stream, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) error { + start := s.cursor + if err := s.skipValue(depth); err != nil { + return err + } + src := s.buf[start:s.cursor] + if bytes.Equal(src, nullbytes) { + *(*unsafe.Pointer)(p) = nil + return nil + } + + dst := make([]byte, len(src)) + copy(dst, src) + + if err := unmarshaler.UnmarshalText(dst); err != nil { + return err + } + return nil +} + +func decodeTextUnmarshaler(buf []byte, cursor, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) (int64, error) { + cursor = skipWhiteSpace(buf, cursor) + start := cursor + end, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + src := buf[start:end] + if bytes.Equal(src, nullbytes) { + *(*unsafe.Pointer)(p) = nil + return end, nil + } + if s, ok := unquoteBytes(src); ok { + src = s + } + if err := unmarshaler.UnmarshalText(src); err != nil { + return 0, err + } + return end, nil +} + +func (d *interfaceDecoder) decodeStreamEmptyInterface(s *Stream, depth int64, p unsafe.Pointer) error { + c := s.skipWhiteSpace() + for { + switch c { + case '{': + var v map[string]interface{} + ptr := unsafe.Pointer(&v) + if err := d.mapDecoder.DecodeStream(s, depth, ptr); err != nil { + return err + } + *(*interface{})(p) = v + return nil + case '[': + var v []interface{} + ptr := unsafe.Pointer(&v) + if err := d.sliceDecoder.DecodeStream(s, depth, ptr); err != nil { + return err + } + *(*interface{})(p) = v + return nil + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return d.numDecoder(s).DecodeStream(s, depth, p) + case '"': + s.cursor++ + start := s.cursor + for { + switch s.char() { + case '\\': + if _, err := decodeEscapeString(s, nil); err != nil { + return err + } + case '"': + literal := s.buf[start:s.cursor] + s.cursor++ + *(*interface{})(p) = string(literal) + return nil + case nul: + if s.read() { + continue + } + return errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + } + s.cursor++ + } + case 't': + if err := trueBytes(s); err != nil { + return err + } + **(**interface{})(unsafe.Pointer(&p)) = true + return nil + case 'f': + if err := falseBytes(s); err != nil { + return err + } + **(**interface{})(unsafe.Pointer(&p)) = false + return nil + case 'n': + if err := nullBytes(s); err != nil { + return err + } + *(*interface{})(p) = nil + return nil + case nul: + if s.read() { + c = s.char() + continue + } + } + break + } + return errors.ErrInvalidBeginningOfValue(c, s.totalOffset()) +} + +type emptyInterface struct { + typ *runtime.Type + ptr unsafe.Pointer +} + +func (d *interfaceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + runtimeInterfaceValue := *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: d.typ, + ptr: p, + })) + rv := reflect.ValueOf(runtimeInterfaceValue) + if rv.NumMethod() > 0 && rv.CanInterface() { + if u, ok := rv.Interface().(unmarshalerContext); ok { + return decodeStreamUnmarshalerContext(s, depth, u) + } + if u, ok := rv.Interface().(json.Unmarshaler); ok { + return decodeStreamUnmarshaler(s, depth, u) + } + if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok { + return decodeStreamTextUnmarshaler(s, depth, u, p) + } + if s.skipWhiteSpace() == 'n' { + if err := nullBytes(s); err != nil { + return err + } + *(*interface{})(p) = nil + return nil + } + return d.errUnmarshalType(rv.Type(), s.totalOffset()) + } + iface := rv.Interface() + ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface)) + typ := ifaceHeader.typ + if ifaceHeader.ptr == nil || d.typ == typ || typ == nil { + // concrete type is empty interface + return d.decodeStreamEmptyInterface(s, depth, p) + } + if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr { + return d.decodeStreamEmptyInterface(s, depth, p) + } + if s.skipWhiteSpace() == 'n' { + if err := nullBytes(s); err != nil { + return err + } + *(*interface{})(p) = nil + return nil + } + decoder, err := CompileToGetDecoder(typ) + if err != nil { + return err + } + return decoder.DecodeStream(s, depth, ifaceHeader.ptr) +} + +func (d *interfaceDecoder) errUnmarshalType(typ reflect.Type, offset int64) *errors.UnmarshalTypeError { + return &errors.UnmarshalTypeError{ + Value: typ.String(), + Type: typ, + Offset: offset, + Struct: d.structName, + Field: d.fieldName, + } +} + +func (d *interfaceDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + runtimeInterfaceValue := *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: d.typ, + ptr: p, + })) + rv := reflect.ValueOf(runtimeInterfaceValue) + if rv.NumMethod() > 0 && rv.CanInterface() { + if u, ok := rv.Interface().(unmarshalerContext); ok { + return decodeUnmarshalerContext(ctx, buf, cursor, depth, u) + } + if u, ok := rv.Interface().(json.Unmarshaler); ok { + return decodeUnmarshaler(buf, cursor, depth, u) + } + if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok { + return decodeTextUnmarshaler(buf, cursor, depth, u, p) + } + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == 'n' { + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + **(**interface{})(unsafe.Pointer(&p)) = nil + return cursor, nil + } + return 0, d.errUnmarshalType(rv.Type(), cursor) + } + + iface := rv.Interface() + ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface)) + typ := ifaceHeader.typ + if ifaceHeader.ptr == nil || d.typ == typ || typ == nil { + // concrete type is empty interface + return d.decodeEmptyInterface(ctx, cursor, depth, p) + } + if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr { + return d.decodeEmptyInterface(ctx, cursor, depth, p) + } + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == 'n' { + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + **(**interface{})(unsafe.Pointer(&p)) = nil + return cursor, nil + } + decoder, err := CompileToGetDecoder(typ) + if err != nil { + return 0, err + } + return decoder.Decode(ctx, cursor, depth, ifaceHeader.ptr) +} + +func (d *interfaceDecoder) decodeEmptyInterface(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + cursor = skipWhiteSpace(buf, cursor) + switch buf[cursor] { + case '{': + var v map[string]interface{} + ptr := unsafe.Pointer(&v) + cursor, err := d.mapDecoder.Decode(ctx, cursor, depth, ptr) + if err != nil { + return 0, err + } + **(**interface{})(unsafe.Pointer(&p)) = v + return cursor, nil + case '[': + var v []interface{} + ptr := unsafe.Pointer(&v) + cursor, err := d.sliceDecoder.Decode(ctx, cursor, depth, ptr) + if err != nil { + return 0, err + } + **(**interface{})(unsafe.Pointer(&p)) = v + return cursor, nil + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return d.floatDecoder.Decode(ctx, cursor, depth, p) + case '"': + var v string + ptr := unsafe.Pointer(&v) + cursor, err := d.stringDecoder.Decode(ctx, cursor, depth, ptr) + if err != nil { + return 0, err + } + **(**interface{})(unsafe.Pointer(&p)) = v + return cursor, nil + case 't': + if err := validateTrue(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + **(**interface{})(unsafe.Pointer(&p)) = true + return cursor, nil + case 'f': + if err := validateFalse(buf, cursor); err != nil { + return 0, err + } + cursor += 5 + **(**interface{})(unsafe.Pointer(&p)) = false + return cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + **(**interface{})(unsafe.Pointer(&p)) = nil + return cursor, nil + } + return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor) +} + +func NewPathDecoder() Decoder { + ifaceDecoder := &interfaceDecoder{ + typ: emptyInterfaceType, + structName: "", + fieldName: "", + floatDecoder: newFloatDecoder("", "", func(p unsafe.Pointer, v float64) { + *(*interface{})(p) = v + }), + numberDecoder: newNumberDecoder("", "", func(p unsafe.Pointer, v json.Number) { + *(*interface{})(p) = v + }), + stringDecoder: newStringDecoder("", ""), + } + ifaceDecoder.sliceDecoder = newSliceDecoder( + ifaceDecoder, + emptyInterfaceType, + emptyInterfaceType.Size(), + "", "", + ) + ifaceDecoder.mapDecoder = newMapDecoder( + interfaceMapType, + stringType, + ifaceDecoder.stringDecoder, + interfaceMapType.Elem(), + ifaceDecoder, + "", "", + ) + return ifaceDecoder +} + +var ( + truebytes = []byte("true") + falsebytes = []byte("false") +) + +func (d *interfaceDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + buf := ctx.Buf + cursor = skipWhiteSpace(buf, cursor) + switch buf[cursor] { + case '{': + return d.mapDecoder.DecodePath(ctx, cursor, depth) + case '[': + return d.sliceDecoder.DecodePath(ctx, cursor, depth) + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return d.floatDecoder.DecodePath(ctx, cursor, depth) + case '"': + return d.stringDecoder.DecodePath(ctx, cursor, depth) + case 't': + if err := validateTrue(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return [][]byte{truebytes}, cursor, nil + case 'f': + if err := validateFalse(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 5 + return [][]byte{falsebytes}, cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return [][]byte{nullbytes}, cursor, nil + } + return nil, cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor) +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/invalid.go b/vendor/github.com/goccy/go-json/internal/decoder/invalid.go new file mode 100644 index 000000000..4c9721b09 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/invalid.go @@ -0,0 +1,55 @@ +package decoder + +import ( + "reflect" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type invalidDecoder struct { + typ *runtime.Type + kind reflect.Kind + structName string + fieldName string +} + +func newInvalidDecoder(typ *runtime.Type, structName, fieldName string) *invalidDecoder { + return &invalidDecoder{ + typ: typ, + kind: typ.Kind(), + structName: structName, + fieldName: fieldName, + } +} + +func (d *invalidDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + return &errors.UnmarshalTypeError{ + Value: "object", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + Struct: d.structName, + Field: d.fieldName, + } +} + +func (d *invalidDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + return 0, &errors.UnmarshalTypeError{ + Value: "object", + Type: runtime.RType2Type(d.typ), + Offset: cursor, + Struct: d.structName, + Field: d.fieldName, + } +} + +func (d *invalidDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + return nil, 0, &errors.UnmarshalTypeError{ + Value: "object", + Type: runtime.RType2Type(d.typ), + Offset: cursor, + Struct: d.structName, + Field: d.fieldName, + } +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/map.go b/vendor/github.com/goccy/go-json/internal/decoder/map.go new file mode 100644 index 000000000..07a9caea6 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/map.go @@ -0,0 +1,280 @@ +package decoder + +import ( + "reflect" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type mapDecoder struct { + mapType *runtime.Type + keyType *runtime.Type + valueType *runtime.Type + canUseAssignFaststrType bool + keyDecoder Decoder + valueDecoder Decoder + structName string + fieldName string +} + +func newMapDecoder(mapType *runtime.Type, keyType *runtime.Type, keyDec Decoder, valueType *runtime.Type, valueDec Decoder, structName, fieldName string) *mapDecoder { + return &mapDecoder{ + mapType: mapType, + keyDecoder: keyDec, + keyType: keyType, + canUseAssignFaststrType: canUseAssignFaststrType(keyType, valueType), + valueType: valueType, + valueDecoder: valueDec, + structName: structName, + fieldName: fieldName, + } +} + +const ( + mapMaxElemSize = 128 +) + +// See detail: https://github.com/goccy/go-json/pull/283 +func canUseAssignFaststrType(key *runtime.Type, value *runtime.Type) bool { + indirectElem := value.Size() > mapMaxElemSize + if indirectElem { + return false + } + return key.Kind() == reflect.String +} + +//go:linkname makemap reflect.makemap +func makemap(*runtime.Type, int) unsafe.Pointer + +//nolint:golint +//go:linkname mapassign_faststr runtime.mapassign_faststr +//go:noescape +func mapassign_faststr(t *runtime.Type, m unsafe.Pointer, s string) unsafe.Pointer + +//go:linkname mapassign reflect.mapassign +//go:noescape +func mapassign(t *runtime.Type, m unsafe.Pointer, k, v unsafe.Pointer) + +func (d *mapDecoder) mapassign(t *runtime.Type, m, k, v unsafe.Pointer) { + if d.canUseAssignFaststrType { + mapV := mapassign_faststr(t, m, *(*string)(k)) + typedmemmove(d.valueType, mapV, v) + } else { + mapassign(t, m, k, v) + } +} + +func (d *mapDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + + switch s.skipWhiteSpace() { + case 'n': + if err := nullBytes(s); err != nil { + return err + } + **(**unsafe.Pointer)(unsafe.Pointer(&p)) = nil + return nil + case '{': + default: + return errors.ErrExpected("{ character for map value", s.totalOffset()) + } + mapValue := *(*unsafe.Pointer)(p) + if mapValue == nil { + mapValue = makemap(d.mapType, 0) + } + s.cursor++ + if s.skipWhiteSpace() == '}' { + *(*unsafe.Pointer)(p) = mapValue + s.cursor++ + return nil + } + for { + k := unsafe_New(d.keyType) + if err := d.keyDecoder.DecodeStream(s, depth, k); err != nil { + return err + } + s.skipWhiteSpace() + if !s.equalChar(':') { + return errors.ErrExpected("colon after object key", s.totalOffset()) + } + s.cursor++ + v := unsafe_New(d.valueType) + if err := d.valueDecoder.DecodeStream(s, depth, v); err != nil { + return err + } + d.mapassign(d.mapType, mapValue, k, v) + s.skipWhiteSpace() + if s.equalChar('}') { + **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue + s.cursor++ + return nil + } + if !s.equalChar(',') { + return errors.ErrExpected("comma after object value", s.totalOffset()) + } + s.cursor++ + } +} + +func (d *mapDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + + cursor = skipWhiteSpace(buf, cursor) + buflen := int64(len(buf)) + if buflen < 2 { + return 0, errors.ErrExpected("{} for map", cursor) + } + switch buf[cursor] { + case 'n': + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + **(**unsafe.Pointer)(unsafe.Pointer(&p)) = nil + return cursor, nil + case '{': + default: + return 0, errors.ErrExpected("{ character for map value", cursor) + } + cursor++ + cursor = skipWhiteSpace(buf, cursor) + mapValue := *(*unsafe.Pointer)(p) + if mapValue == nil { + mapValue = makemap(d.mapType, 0) + } + if buf[cursor] == '}' { + **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue + cursor++ + return cursor, nil + } + for { + k := unsafe_New(d.keyType) + keyCursor, err := d.keyDecoder.Decode(ctx, cursor, depth, k) + if err != nil { + return 0, err + } + cursor = skipWhiteSpace(buf, keyCursor) + if buf[cursor] != ':' { + return 0, errors.ErrExpected("colon after object key", cursor) + } + cursor++ + v := unsafe_New(d.valueType) + valueCursor, err := d.valueDecoder.Decode(ctx, cursor, depth, v) + if err != nil { + return 0, err + } + d.mapassign(d.mapType, mapValue, k, v) + cursor = skipWhiteSpace(buf, valueCursor) + if buf[cursor] == '}' { + **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue + cursor++ + return cursor, nil + } + if buf[cursor] != ',' { + return 0, errors.ErrExpected("comma after object value", cursor) + } + cursor++ + } +} + +func (d *mapDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + buf := ctx.Buf + depth++ + if depth > maxDecodeNestingDepth { + return nil, 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + + cursor = skipWhiteSpace(buf, cursor) + buflen := int64(len(buf)) + if buflen < 2 { + return nil, 0, errors.ErrExpected("{} for map", cursor) + } + switch buf[cursor] { + case 'n': + if err := validateNull(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return [][]byte{nullbytes}, cursor, nil + case '{': + default: + return nil, 0, errors.ErrExpected("{ character for map value", cursor) + } + cursor++ + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == '}' { + cursor++ + return nil, cursor, nil + } + keyDecoder, ok := d.keyDecoder.(*stringDecoder) + if !ok { + return nil, 0, &errors.UnmarshalTypeError{ + Value: "string", + Type: reflect.TypeOf(""), + Offset: cursor, + Struct: d.structName, + Field: d.fieldName, + } + } + ret := [][]byte{} + for { + key, keyCursor, err := keyDecoder.decodeByte(buf, cursor) + if err != nil { + return nil, 0, err + } + cursor = skipWhiteSpace(buf, keyCursor) + if buf[cursor] != ':' { + return nil, 0, errors.ErrExpected("colon after object key", cursor) + } + cursor++ + child, found, err := ctx.Option.Path.Field(string(key)) + if err != nil { + return nil, 0, err + } + if found { + if child != nil { + oldPath := ctx.Option.Path.node + ctx.Option.Path.node = child + paths, c, err := d.valueDecoder.DecodePath(ctx, cursor, depth) + if err != nil { + return nil, 0, err + } + ctx.Option.Path.node = oldPath + ret = append(ret, paths...) + cursor = c + } else { + start := cursor + end, err := skipValue(buf, cursor, depth) + if err != nil { + return nil, 0, err + } + ret = append(ret, buf[start:end]) + cursor = end + } + } else { + c, err := skipValue(buf, cursor, depth) + if err != nil { + return nil, 0, err + } + cursor = c + } + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == '}' { + cursor++ + return ret, cursor, nil + } + if buf[cursor] != ',' { + return nil, 0, errors.ErrExpected("comma after object value", cursor) + } + cursor++ + } +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/number.go b/vendor/github.com/goccy/go-json/internal/decoder/number.go new file mode 100644 index 000000000..10e5435e6 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/number.go @@ -0,0 +1,123 @@ +package decoder + +import ( + "encoding/json" + "strconv" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +type numberDecoder struct { + stringDecoder *stringDecoder + op func(unsafe.Pointer, json.Number) + structName string + fieldName string +} + +func newNumberDecoder(structName, fieldName string, op func(unsafe.Pointer, json.Number)) *numberDecoder { + return &numberDecoder{ + stringDecoder: newStringDecoder(structName, fieldName), + op: op, + structName: structName, + fieldName: fieldName, + } +} + +func (d *numberDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + bytes, err := d.decodeStreamByte(s) + if err != nil { + return err + } + if _, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&bytes)), 64); err != nil { + return errors.ErrSyntax(err.Error(), s.totalOffset()) + } + d.op(p, json.Number(string(bytes))) + s.reset() + return nil +} + +func (d *numberDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + bytes, c, err := d.decodeByte(ctx.Buf, cursor) + if err != nil { + return 0, err + } + if _, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&bytes)), 64); err != nil { + return 0, errors.ErrSyntax(err.Error(), c) + } + cursor = c + s := *(*string)(unsafe.Pointer(&bytes)) + d.op(p, json.Number(s)) + return cursor, nil +} + +func (d *numberDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + bytes, c, err := d.decodeByte(ctx.Buf, cursor) + if err != nil { + return nil, 0, err + } + if bytes == nil { + return [][]byte{nullbytes}, c, nil + } + return [][]byte{bytes}, c, nil +} + +func (d *numberDecoder) decodeStreamByte(s *Stream) ([]byte, error) { + start := s.cursor + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + s.cursor++ + continue + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return floatBytes(s), nil + case 'n': + if err := nullBytes(s); err != nil { + return nil, err + } + return nil, nil + case '"': + return d.stringDecoder.decodeStreamByte(s) + case nul: + if s.read() { + continue + } + goto ERROR + default: + goto ERROR + } + } +ERROR: + if s.cursor == start { + return nil, errors.ErrInvalidBeginningOfValue(s.char(), s.totalOffset()) + } + return nil, errors.ErrUnexpectedEndOfJSON("json.Number", s.totalOffset()) +} + +func (d *numberDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) { + for { + switch buf[cursor] { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + start := cursor + cursor++ + for floatTable[buf[cursor]] { + cursor++ + } + num := buf[start:cursor] + return num, cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return nil, cursor, nil + case '"': + return d.stringDecoder.decodeByte(buf, cursor) + default: + return nil, 0, errors.ErrUnexpectedEndOfJSON("json.Number", cursor) + } + } +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/option.go b/vendor/github.com/goccy/go-json/internal/decoder/option.go new file mode 100644 index 000000000..502f772eb --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/option.go @@ -0,0 +1,17 @@ +package decoder + +import "context" + +type OptionFlags uint8 + +const ( + FirstWinOption OptionFlags = 1 << iota + ContextOption + PathOption +) + +type Option struct { + Flags OptionFlags + Context context.Context + Path *Path +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/path.go b/vendor/github.com/goccy/go-json/internal/decoder/path.go new file mode 100644 index 000000000..a15ff69e3 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/path.go @@ -0,0 +1,670 @@ +package decoder + +import ( + "fmt" + "reflect" + "strconv" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type PathString string + +func (s PathString) Build() (*Path, error) { + builder := new(PathBuilder) + return builder.Build([]rune(s)) +} + +type PathBuilder struct { + root PathNode + node PathNode + singleQuotePathSelector bool + doubleQuotePathSelector bool +} + +func (b *PathBuilder) Build(buf []rune) (*Path, error) { + node, err := b.build(buf) + if err != nil { + return nil, err + } + return &Path{ + node: node, + RootSelectorOnly: node == nil, + SingleQuotePathSelector: b.singleQuotePathSelector, + DoubleQuotePathSelector: b.doubleQuotePathSelector, + }, nil +} + +func (b *PathBuilder) build(buf []rune) (PathNode, error) { + if len(buf) == 0 { + return nil, errors.ErrEmptyPath() + } + if buf[0] != '$' { + return nil, errors.ErrInvalidPath("JSON Path must start with a $ character") + } + if len(buf) == 1 { + return nil, nil + } + buf = buf[1:] + offset, err := b.buildNext(buf) + if err != nil { + return nil, err + } + if len(buf) > offset { + return nil, errors.ErrInvalidPath("remain invalid path %q", buf[offset:]) + } + return b.root, nil +} + +func (b *PathBuilder) buildNextCharIfExists(buf []rune, cursor int) (int, error) { + if len(buf) > cursor { + offset, err := b.buildNext(buf[cursor:]) + if err != nil { + return 0, err + } + return cursor + 1 + offset, nil + } + return cursor, nil +} + +func (b *PathBuilder) buildNext(buf []rune) (int, error) { + switch buf[0] { + case '.': + if len(buf) == 1 { + return 0, errors.ErrInvalidPath("JSON Path ends with dot character") + } + offset, err := b.buildSelector(buf[1:]) + if err != nil { + return 0, err + } + return offset + 1, nil + case '[': + if len(buf) == 1 { + return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character") + } + offset, err := b.buildIndex(buf[1:]) + if err != nil { + return 0, err + } + return offset + 1, nil + default: + return 0, errors.ErrInvalidPath("expect dot or left bracket character. but found %c character", buf[0]) + } +} + +func (b *PathBuilder) buildSelector(buf []rune) (int, error) { + switch buf[0] { + case '.': + if len(buf) == 1 { + return 0, errors.ErrInvalidPath("JSON Path ends with double dot character") + } + offset, err := b.buildPathRecursive(buf[1:]) + if err != nil { + return 0, err + } + return 1 + offset, nil + case '[', ']', '$', '*': + return 0, errors.ErrInvalidPath("found invalid path character %c after dot", buf[0]) + } + for cursor := 0; cursor < len(buf); cursor++ { + switch buf[cursor] { + case '$', '*', ']': + return 0, errors.ErrInvalidPath("found %c character in field selector context", buf[cursor]) + case '.': + if cursor+1 >= len(buf) { + return 0, errors.ErrInvalidPath("JSON Path ends with dot character") + } + selector := buf[:cursor] + b.addSelectorNode(string(selector)) + offset, err := b.buildSelector(buf[cursor+1:]) + if err != nil { + return 0, err + } + return cursor + 1 + offset, nil + case '[': + if cursor+1 >= len(buf) { + return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character") + } + selector := buf[:cursor] + b.addSelectorNode(string(selector)) + offset, err := b.buildIndex(buf[cursor+1:]) + if err != nil { + return 0, err + } + return cursor + 1 + offset, nil + case '"': + if cursor+1 >= len(buf) { + return 0, errors.ErrInvalidPath("JSON Path ends with double quote character") + } + offset, err := b.buildQuoteSelector(buf[cursor+1:], DoubleQuotePathSelector) + if err != nil { + return 0, err + } + return cursor + 1 + offset, nil + } + } + b.addSelectorNode(string(buf)) + return len(buf), nil +} + +func (b *PathBuilder) buildQuoteSelector(buf []rune, sel QuotePathSelector) (int, error) { + switch buf[0] { + case '[', ']', '$', '.', '*', '\'', '"': + return 0, errors.ErrInvalidPath("found invalid path character %c after quote", buf[0]) + } + for cursor := 0; cursor < len(buf); cursor++ { + switch buf[cursor] { + case '\'': + if sel != SingleQuotePathSelector { + return 0, errors.ErrInvalidPath("found double quote character in field selector with single quote context") + } + if len(buf) <= cursor+1 { + return 0, errors.ErrInvalidPath("JSON Path ends with single quote character in field selector context") + } + if buf[cursor+1] != ']' { + return 0, errors.ErrInvalidPath("expect right bracket for field selector with single quote but found %c", buf[cursor+1]) + } + selector := buf[:cursor] + b.addSelectorNode(string(selector)) + b.singleQuotePathSelector = true + return b.buildNextCharIfExists(buf, cursor+2) + case '"': + if sel != DoubleQuotePathSelector { + return 0, errors.ErrInvalidPath("found single quote character in field selector with double quote context") + } + selector := buf[:cursor] + b.addSelectorNode(string(selector)) + b.doubleQuotePathSelector = true + return b.buildNextCharIfExists(buf, cursor+1) + } + } + return 0, errors.ErrInvalidPath("couldn't find quote character in selector quote path context") +} + +func (b *PathBuilder) buildPathRecursive(buf []rune) (int, error) { + switch buf[0] { + case '.', '[', ']', '$', '*': + return 0, errors.ErrInvalidPath("found invalid path character %c after double dot", buf[0]) + } + for cursor := 0; cursor < len(buf); cursor++ { + switch buf[cursor] { + case '$', '*', ']': + return 0, errors.ErrInvalidPath("found %c character in field selector context", buf[cursor]) + case '.': + if cursor+1 >= len(buf) { + return 0, errors.ErrInvalidPath("JSON Path ends with dot character") + } + selector := buf[:cursor] + b.addRecursiveNode(string(selector)) + offset, err := b.buildSelector(buf[cursor+1:]) + if err != nil { + return 0, err + } + return cursor + 1 + offset, nil + case '[': + if cursor+1 >= len(buf) { + return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character") + } + selector := buf[:cursor] + b.addRecursiveNode(string(selector)) + offset, err := b.buildIndex(buf[cursor+1:]) + if err != nil { + return 0, err + } + return cursor + 1 + offset, nil + } + } + b.addRecursiveNode(string(buf)) + return len(buf), nil +} + +func (b *PathBuilder) buildIndex(buf []rune) (int, error) { + switch buf[0] { + case '.', '[', ']', '$': + return 0, errors.ErrInvalidPath("found invalid path character %c after left bracket", buf[0]) + case '\'': + if len(buf) == 1 { + return 0, errors.ErrInvalidPath("JSON Path ends with single quote character") + } + offset, err := b.buildQuoteSelector(buf[1:], SingleQuotePathSelector) + if err != nil { + return 0, err + } + return 1 + offset, nil + case '*': + if len(buf) == 1 { + return 0, errors.ErrInvalidPath("JSON Path ends with star character") + } + if buf[1] != ']' { + return 0, errors.ErrInvalidPath("expect right bracket character for index all path but found %c character", buf[1]) + } + b.addIndexAllNode() + offset := len("*]") + if len(buf) > 2 { + buildOffset, err := b.buildNext(buf[2:]) + if err != nil { + return 0, err + } + return offset + buildOffset, nil + } + return offset, nil + } + + for cursor := 0; cursor < len(buf); cursor++ { + switch buf[cursor] { + case ']': + index, err := strconv.ParseInt(string(buf[:cursor]), 10, 64) + if err != nil { + return 0, errors.ErrInvalidPath("%q is unexpected index path", buf[:cursor]) + } + b.addIndexNode(int(index)) + return b.buildNextCharIfExists(buf, cursor+1) + } + } + return 0, errors.ErrInvalidPath("couldn't find right bracket character in index path context") +} + +func (b *PathBuilder) addIndexAllNode() { + node := newPathIndexAllNode() + if b.root == nil { + b.root = node + b.node = node + } else { + b.node = b.node.chain(node) + } +} + +func (b *PathBuilder) addRecursiveNode(selector string) { + node := newPathRecursiveNode(selector) + if b.root == nil { + b.root = node + b.node = node + } else { + b.node = b.node.chain(node) + } +} + +func (b *PathBuilder) addSelectorNode(name string) { + node := newPathSelectorNode(name) + if b.root == nil { + b.root = node + b.node = node + } else { + b.node = b.node.chain(node) + } +} + +func (b *PathBuilder) addIndexNode(idx int) { + node := newPathIndexNode(idx) + if b.root == nil { + b.root = node + b.node = node + } else { + b.node = b.node.chain(node) + } +} + +type QuotePathSelector int + +const ( + SingleQuotePathSelector QuotePathSelector = 1 + DoubleQuotePathSelector QuotePathSelector = 2 +) + +type Path struct { + node PathNode + RootSelectorOnly bool + SingleQuotePathSelector bool + DoubleQuotePathSelector bool +} + +func (p *Path) Field(sel string) (PathNode, bool, error) { + if p.node == nil { + return nil, false, nil + } + return p.node.Field(sel) +} + +func (p *Path) Get(src, dst reflect.Value) error { + if p.node == nil { + return nil + } + return p.node.Get(src, dst) +} + +func (p *Path) String() string { + if p.node == nil { + return "$" + } + return p.node.String() +} + +type PathNode interface { + fmt.Stringer + Index(idx int) (PathNode, bool, error) + Field(fieldName string) (PathNode, bool, error) + Get(src, dst reflect.Value) error + chain(PathNode) PathNode + target() bool + single() bool +} + +type BasePathNode struct { + child PathNode +} + +func (n *BasePathNode) chain(node PathNode) PathNode { + n.child = node + return node +} + +func (n *BasePathNode) target() bool { + return n.child == nil +} + +func (n *BasePathNode) single() bool { + return true +} + +type PathSelectorNode struct { + *BasePathNode + selector string +} + +func newPathSelectorNode(selector string) *PathSelectorNode { + return &PathSelectorNode{ + BasePathNode: &BasePathNode{}, + selector: selector, + } +} + +func (n *PathSelectorNode) Index(idx int) (PathNode, bool, error) { + return nil, false, &errors.PathError{} +} + +func (n *PathSelectorNode) Field(fieldName string) (PathNode, bool, error) { + if n.selector == fieldName { + return n.child, true, nil + } + return nil, false, nil +} + +func (n *PathSelectorNode) Get(src, dst reflect.Value) error { + switch src.Type().Kind() { + case reflect.Map: + iter := src.MapRange() + for iter.Next() { + key, ok := iter.Key().Interface().(string) + if !ok { + return fmt.Errorf("invalid map key type %T", src.Type().Key()) + } + child, found, err := n.Field(key) + if err != nil { + return err + } + if found { + if child != nil { + return child.Get(iter.Value(), dst) + } + return AssignValue(iter.Value(), dst) + } + } + case reflect.Struct: + typ := src.Type() + for i := 0; i < typ.Len(); i++ { + tag := runtime.StructTagFromField(typ.Field(i)) + child, found, err := n.Field(tag.Key) + if err != nil { + return err + } + if found { + if child != nil { + return child.Get(src.Field(i), dst) + } + return AssignValue(src.Field(i), dst) + } + } + case reflect.Ptr: + return n.Get(src.Elem(), dst) + case reflect.Interface: + return n.Get(reflect.ValueOf(src.Interface()), dst) + case reflect.Float64, reflect.String, reflect.Bool: + return AssignValue(src, dst) + } + return fmt.Errorf("failed to get %s value from %s", n.selector, src.Type()) +} + +func (n *PathSelectorNode) String() string { + s := fmt.Sprintf(".%s", n.selector) + if n.child != nil { + s += n.child.String() + } + return s +} + +type PathIndexNode struct { + *BasePathNode + selector int +} + +func newPathIndexNode(selector int) *PathIndexNode { + return &PathIndexNode{ + BasePathNode: &BasePathNode{}, + selector: selector, + } +} + +func (n *PathIndexNode) Index(idx int) (PathNode, bool, error) { + if n.selector == idx { + return n.child, true, nil + } + return nil, false, nil +} + +func (n *PathIndexNode) Field(fieldName string) (PathNode, bool, error) { + return nil, false, &errors.PathError{} +} + +func (n *PathIndexNode) Get(src, dst reflect.Value) error { + switch src.Type().Kind() { + case reflect.Array, reflect.Slice: + if src.Len() > n.selector { + if n.child != nil { + return n.child.Get(src.Index(n.selector), dst) + } + return AssignValue(src.Index(n.selector), dst) + } + case reflect.Ptr: + return n.Get(src.Elem(), dst) + case reflect.Interface: + return n.Get(reflect.ValueOf(src.Interface()), dst) + } + return fmt.Errorf("failed to get [%d] value from %s", n.selector, src.Type()) +} + +func (n *PathIndexNode) String() string { + s := fmt.Sprintf("[%d]", n.selector) + if n.child != nil { + s += n.child.String() + } + return s +} + +type PathIndexAllNode struct { + *BasePathNode +} + +func newPathIndexAllNode() *PathIndexAllNode { + return &PathIndexAllNode{ + BasePathNode: &BasePathNode{}, + } +} + +func (n *PathIndexAllNode) Index(idx int) (PathNode, bool, error) { + return n.child, true, nil +} + +func (n *PathIndexAllNode) Field(fieldName string) (PathNode, bool, error) { + return nil, false, &errors.PathError{} +} + +func (n *PathIndexAllNode) Get(src, dst reflect.Value) error { + switch src.Type().Kind() { + case reflect.Array, reflect.Slice: + var arr []interface{} + for i := 0; i < src.Len(); i++ { + var v interface{} + rv := reflect.ValueOf(&v) + if n.child != nil { + if err := n.child.Get(src.Index(i), rv); err != nil { + return err + } + } else { + if err := AssignValue(src.Index(i), rv); err != nil { + return err + } + } + arr = append(arr, v) + } + if err := AssignValue(reflect.ValueOf(arr), dst); err != nil { + return err + } + return nil + case reflect.Ptr: + return n.Get(src.Elem(), dst) + case reflect.Interface: + return n.Get(reflect.ValueOf(src.Interface()), dst) + } + return fmt.Errorf("failed to get all value from %s", src.Type()) +} + +func (n *PathIndexAllNode) String() string { + s := "[*]" + if n.child != nil { + s += n.child.String() + } + return s +} + +type PathRecursiveNode struct { + *BasePathNode + selector string +} + +func newPathRecursiveNode(selector string) *PathRecursiveNode { + node := newPathSelectorNode(selector) + return &PathRecursiveNode{ + BasePathNode: &BasePathNode{ + child: node, + }, + selector: selector, + } +} + +func (n *PathRecursiveNode) Field(fieldName string) (PathNode, bool, error) { + if n.selector == fieldName { + return n.child, true, nil + } + return nil, false, nil +} + +func (n *PathRecursiveNode) Index(_ int) (PathNode, bool, error) { + return n, true, nil +} + +func valueToSliceValue(v interface{}) []interface{} { + rv := reflect.ValueOf(v) + ret := []interface{}{} + if rv.Type().Kind() == reflect.Slice || rv.Type().Kind() == reflect.Array { + for i := 0; i < rv.Len(); i++ { + ret = append(ret, rv.Index(i).Interface()) + } + return ret + } + return []interface{}{v} +} + +func (n *PathRecursiveNode) Get(src, dst reflect.Value) error { + if n.child == nil { + return fmt.Errorf("failed to get by recursive path ..%s", n.selector) + } + var arr []interface{} + switch src.Type().Kind() { + case reflect.Map: + iter := src.MapRange() + for iter.Next() { + key, ok := iter.Key().Interface().(string) + if !ok { + return fmt.Errorf("invalid map key type %T", src.Type().Key()) + } + child, found, err := n.Field(key) + if err != nil { + return err + } + if found { + var v interface{} + rv := reflect.ValueOf(&v) + _ = child.Get(iter.Value(), rv) + arr = append(arr, valueToSliceValue(v)...) + } else { + var v interface{} + rv := reflect.ValueOf(&v) + _ = n.Get(iter.Value(), rv) + if v != nil { + arr = append(arr, valueToSliceValue(v)...) + } + } + } + _ = AssignValue(reflect.ValueOf(arr), dst) + return nil + case reflect.Struct: + typ := src.Type() + for i := 0; i < typ.Len(); i++ { + tag := runtime.StructTagFromField(typ.Field(i)) + child, found, err := n.Field(tag.Key) + if err != nil { + return err + } + if found { + var v interface{} + rv := reflect.ValueOf(&v) + _ = child.Get(src.Field(i), rv) + arr = append(arr, valueToSliceValue(v)...) + } else { + var v interface{} + rv := reflect.ValueOf(&v) + _ = n.Get(src.Field(i), rv) + if v != nil { + arr = append(arr, valueToSliceValue(v)...) + } + } + } + _ = AssignValue(reflect.ValueOf(arr), dst) + return nil + case reflect.Array, reflect.Slice: + for i := 0; i < src.Len(); i++ { + var v interface{} + rv := reflect.ValueOf(&v) + _ = n.Get(src.Index(i), rv) + if v != nil { + arr = append(arr, valueToSliceValue(v)...) + } + } + _ = AssignValue(reflect.ValueOf(arr), dst) + return nil + case reflect.Ptr: + return n.Get(src.Elem(), dst) + case reflect.Interface: + return n.Get(reflect.ValueOf(src.Interface()), dst) + } + return fmt.Errorf("failed to get %s value from %s", n.selector, src.Type()) +} + +func (n *PathRecursiveNode) String() string { + s := fmt.Sprintf("..%s", n.selector) + if n.child != nil { + s += n.child.String() + } + return s +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/ptr.go b/vendor/github.com/goccy/go-json/internal/decoder/ptr.go new file mode 100644 index 000000000..de12e105c --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/ptr.go @@ -0,0 +1,96 @@ +package decoder + +import ( + "fmt" + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +type ptrDecoder struct { + dec Decoder + typ *runtime.Type + structName string + fieldName string +} + +func newPtrDecoder(dec Decoder, typ *runtime.Type, structName, fieldName string) *ptrDecoder { + return &ptrDecoder{ + dec: dec, + typ: typ, + structName: structName, + fieldName: fieldName, + } +} + +func (d *ptrDecoder) contentDecoder() Decoder { + dec, ok := d.dec.(*ptrDecoder) + if !ok { + return d.dec + } + return dec.contentDecoder() +} + +//nolint:golint +//go:linkname unsafe_New reflect.unsafe_New +func unsafe_New(*runtime.Type) unsafe.Pointer + +func UnsafeNew(t *runtime.Type) unsafe.Pointer { + return unsafe_New(t) +} + +func (d *ptrDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + if s.skipWhiteSpace() == nul { + s.read() + } + if s.char() == 'n' { + if err := nullBytes(s); err != nil { + return err + } + *(*unsafe.Pointer)(p) = nil + return nil + } + var newptr unsafe.Pointer + if *(*unsafe.Pointer)(p) == nil { + newptr = unsafe_New(d.typ) + *(*unsafe.Pointer)(p) = newptr + } else { + newptr = *(*unsafe.Pointer)(p) + } + if err := d.dec.DecodeStream(s, depth, newptr); err != nil { + return err + } + return nil +} + +func (d *ptrDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == 'n' { + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + if p != nil { + *(*unsafe.Pointer)(p) = nil + } + cursor += 4 + return cursor, nil + } + var newptr unsafe.Pointer + if *(*unsafe.Pointer)(p) == nil { + newptr = unsafe_New(d.typ) + *(*unsafe.Pointer)(p) = newptr + } else { + newptr = *(*unsafe.Pointer)(p) + } + c, err := d.dec.Decode(ctx, cursor, depth, newptr) + if err != nil { + return 0, err + } + cursor = c + return cursor, nil +} + +func (d *ptrDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + return nil, 0, fmt.Errorf("json: ptr decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/slice.go b/vendor/github.com/goccy/go-json/internal/decoder/slice.go new file mode 100644 index 000000000..30a23e4b5 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/slice.go @@ -0,0 +1,380 @@ +package decoder + +import ( + "reflect" + "sync" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +var ( + sliceType = runtime.Type2RType( + reflect.TypeOf((*sliceHeader)(nil)).Elem(), + ) + nilSlice = unsafe.Pointer(&sliceHeader{}) +) + +type sliceDecoder struct { + elemType *runtime.Type + isElemPointerType bool + valueDecoder Decoder + size uintptr + arrayPool sync.Pool + structName string + fieldName string +} + +// If use reflect.SliceHeader, data type is uintptr. +// In this case, Go compiler cannot trace reference created by newArray(). +// So, define using unsafe.Pointer as data type +type sliceHeader struct { + data unsafe.Pointer + len int + cap int +} + +const ( + defaultSliceCapacity = 2 +) + +func newSliceDecoder(dec Decoder, elemType *runtime.Type, size uintptr, structName, fieldName string) *sliceDecoder { + return &sliceDecoder{ + valueDecoder: dec, + elemType: elemType, + isElemPointerType: elemType.Kind() == reflect.Ptr || elemType.Kind() == reflect.Map, + size: size, + arrayPool: sync.Pool{ + New: func() interface{} { + return &sliceHeader{ + data: newArray(elemType, defaultSliceCapacity), + len: 0, + cap: defaultSliceCapacity, + } + }, + }, + structName: structName, + fieldName: fieldName, + } +} + +func (d *sliceDecoder) newSlice(src *sliceHeader) *sliceHeader { + slice := d.arrayPool.Get().(*sliceHeader) + if src.len > 0 { + // copy original elem + if slice.cap < src.cap { + data := newArray(d.elemType, src.cap) + slice = &sliceHeader{data: data, len: src.len, cap: src.cap} + } else { + slice.len = src.len + } + copySlice(d.elemType, *slice, *src) + } else { + slice.len = 0 + } + return slice +} + +func (d *sliceDecoder) releaseSlice(p *sliceHeader) { + d.arrayPool.Put(p) +} + +//go:linkname copySlice reflect.typedslicecopy +func copySlice(elemType *runtime.Type, dst, src sliceHeader) int + +//go:linkname newArray reflect.unsafe_NewArray +func newArray(*runtime.Type, int) unsafe.Pointer + +//go:linkname typedmemmove reflect.typedmemmove +func typedmemmove(t *runtime.Type, dst, src unsafe.Pointer) + +func (d *sliceDecoder) errNumber(offset int64) *errors.UnmarshalTypeError { + return &errors.UnmarshalTypeError{ + Value: "number", + Type: reflect.SliceOf(runtime.RType2Type(d.elemType)), + Struct: d.structName, + Field: d.fieldName, + Offset: offset, + } +} + +func (d *sliceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + s.cursor++ + continue + case 'n': + if err := nullBytes(s); err != nil { + return err + } + typedmemmove(sliceType, p, nilSlice) + return nil + case '[': + s.cursor++ + if s.skipWhiteSpace() == ']' { + dst := (*sliceHeader)(p) + if dst.data == nil { + dst.data = newArray(d.elemType, 0) + } else { + dst.len = 0 + } + s.cursor++ + return nil + } + idx := 0 + slice := d.newSlice((*sliceHeader)(p)) + srcLen := slice.len + capacity := slice.cap + data := slice.data + for { + if capacity <= idx { + src := sliceHeader{data: data, len: idx, cap: capacity} + capacity *= 2 + data = newArray(d.elemType, capacity) + dst := sliceHeader{data: data, len: idx, cap: capacity} + copySlice(d.elemType, dst, src) + } + ep := unsafe.Pointer(uintptr(data) + uintptr(idx)*d.size) + + // if srcLen is greater than idx, keep the original reference + if srcLen <= idx { + if d.isElemPointerType { + **(**unsafe.Pointer)(unsafe.Pointer(&ep)) = nil // initialize elem pointer + } else { + // assign new element to the slice + typedmemmove(d.elemType, ep, unsafe_New(d.elemType)) + } + } + + if err := d.valueDecoder.DecodeStream(s, depth, ep); err != nil { + return err + } + s.skipWhiteSpace() + RETRY: + switch s.char() { + case ']': + slice.cap = capacity + slice.len = idx + 1 + slice.data = data + dst := (*sliceHeader)(p) + dst.len = idx + 1 + if dst.len > dst.cap { + dst.data = newArray(d.elemType, dst.len) + dst.cap = dst.len + } + copySlice(d.elemType, *dst, *slice) + d.releaseSlice(slice) + s.cursor++ + return nil + case ',': + idx++ + case nul: + if s.read() { + goto RETRY + } + slice.cap = capacity + slice.data = data + d.releaseSlice(slice) + goto ERROR + default: + slice.cap = capacity + slice.data = data + d.releaseSlice(slice) + goto ERROR + } + s.cursor++ + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return d.errNumber(s.totalOffset()) + case nul: + if s.read() { + continue + } + goto ERROR + default: + goto ERROR + } + } +ERROR: + return errors.ErrUnexpectedEndOfJSON("slice", s.totalOffset()) +} + +func (d *sliceDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + + for { + switch buf[cursor] { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case 'n': + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + typedmemmove(sliceType, p, nilSlice) + return cursor, nil + case '[': + cursor++ + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == ']' { + dst := (*sliceHeader)(p) + if dst.data == nil { + dst.data = newArray(d.elemType, 0) + } else { + dst.len = 0 + } + cursor++ + return cursor, nil + } + idx := 0 + slice := d.newSlice((*sliceHeader)(p)) + srcLen := slice.len + capacity := slice.cap + data := slice.data + for { + if capacity <= idx { + src := sliceHeader{data: data, len: idx, cap: capacity} + capacity *= 2 + data = newArray(d.elemType, capacity) + dst := sliceHeader{data: data, len: idx, cap: capacity} + copySlice(d.elemType, dst, src) + } + ep := unsafe.Pointer(uintptr(data) + uintptr(idx)*d.size) + // if srcLen is greater than idx, keep the original reference + if srcLen <= idx { + if d.isElemPointerType { + **(**unsafe.Pointer)(unsafe.Pointer(&ep)) = nil // initialize elem pointer + } else { + // assign new element to the slice + typedmemmove(d.elemType, ep, unsafe_New(d.elemType)) + } + } + c, err := d.valueDecoder.Decode(ctx, cursor, depth, ep) + if err != nil { + return 0, err + } + cursor = c + cursor = skipWhiteSpace(buf, cursor) + switch buf[cursor] { + case ']': + slice.cap = capacity + slice.len = idx + 1 + slice.data = data + dst := (*sliceHeader)(p) + dst.len = idx + 1 + if dst.len > dst.cap { + dst.data = newArray(d.elemType, dst.len) + dst.cap = dst.len + } + copySlice(d.elemType, *dst, *slice) + d.releaseSlice(slice) + cursor++ + return cursor, nil + case ',': + idx++ + default: + slice.cap = capacity + slice.data = data + d.releaseSlice(slice) + return 0, errors.ErrInvalidCharacter(buf[cursor], "slice", cursor) + } + cursor++ + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return 0, d.errNumber(cursor) + default: + return 0, errors.ErrUnexpectedEndOfJSON("slice", cursor) + } + } +} + +func (d *sliceDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + buf := ctx.Buf + depth++ + if depth > maxDecodeNestingDepth { + return nil, 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + + ret := [][]byte{} + for { + switch buf[cursor] { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case 'n': + if err := validateNull(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return [][]byte{nullbytes}, cursor, nil + case '[': + cursor++ + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == ']' { + cursor++ + return ret, cursor, nil + } + idx := 0 + for { + child, found, err := ctx.Option.Path.node.Index(idx) + if err != nil { + return nil, 0, err + } + if found { + if child != nil { + oldPath := ctx.Option.Path.node + ctx.Option.Path.node = child + paths, c, err := d.valueDecoder.DecodePath(ctx, cursor, depth) + if err != nil { + return nil, 0, err + } + ctx.Option.Path.node = oldPath + ret = append(ret, paths...) + cursor = c + } else { + start := cursor + end, err := skipValue(buf, cursor, depth) + if err != nil { + return nil, 0, err + } + ret = append(ret, buf[start:end]) + cursor = end + } + } else { + c, err := skipValue(buf, cursor, depth) + if err != nil { + return nil, 0, err + } + cursor = c + } + cursor = skipWhiteSpace(buf, cursor) + switch buf[cursor] { + case ']': + cursor++ + return ret, cursor, nil + case ',': + idx++ + default: + return nil, 0, errors.ErrInvalidCharacter(buf[cursor], "slice", cursor) + } + cursor++ + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return nil, 0, d.errNumber(cursor) + default: + return nil, 0, errors.ErrUnexpectedEndOfJSON("slice", cursor) + } + } +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/stream.go b/vendor/github.com/goccy/go-json/internal/decoder/stream.go new file mode 100644 index 000000000..a383f7259 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/stream.go @@ -0,0 +1,556 @@ +package decoder + +import ( + "bytes" + "encoding/json" + "io" + "strconv" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +const ( + initBufSize = 512 +) + +type Stream struct { + buf []byte + bufSize int64 + length int64 + r io.Reader + offset int64 + cursor int64 + filledBuffer bool + allRead bool + UseNumber bool + DisallowUnknownFields bool + Option *Option +} + +func NewStream(r io.Reader) *Stream { + return &Stream{ + r: r, + bufSize: initBufSize, + buf: make([]byte, initBufSize), + Option: &Option{}, + } +} + +func (s *Stream) TotalOffset() int64 { + return s.totalOffset() +} + +func (s *Stream) Buffered() io.Reader { + buflen := int64(len(s.buf)) + for i := s.cursor; i < buflen; i++ { + if s.buf[i] == nul { + return bytes.NewReader(s.buf[s.cursor:i]) + } + } + return bytes.NewReader(s.buf[s.cursor:]) +} + +func (s *Stream) PrepareForDecode() error { + for { + switch s.char() { + case ' ', '\t', '\r', '\n': + s.cursor++ + continue + case ',', ':': + s.cursor++ + return nil + case nul: + if s.read() { + continue + } + return io.EOF + } + break + } + return nil +} + +func (s *Stream) totalOffset() int64 { + return s.offset + s.cursor +} + +func (s *Stream) char() byte { + return s.buf[s.cursor] +} + +func (s *Stream) equalChar(c byte) bool { + cur := s.buf[s.cursor] + if cur == nul { + s.read() + cur = s.buf[s.cursor] + } + return cur == c +} + +func (s *Stream) stat() ([]byte, int64, unsafe.Pointer) { + return s.buf, s.cursor, (*sliceHeader)(unsafe.Pointer(&s.buf)).data +} + +func (s *Stream) bufptr() unsafe.Pointer { + return (*sliceHeader)(unsafe.Pointer(&s.buf)).data +} + +func (s *Stream) statForRetry() ([]byte, int64, unsafe.Pointer) { + s.cursor-- // for retry ( because caller progress cursor position in each loop ) + return s.buf, s.cursor, (*sliceHeader)(unsafe.Pointer(&s.buf)).data +} + +func (s *Stream) Reset() { + s.reset() + s.bufSize = int64(len(s.buf)) +} + +func (s *Stream) More() bool { + for { + switch s.char() { + case ' ', '\n', '\r', '\t': + s.cursor++ + continue + case '}', ']': + return false + case nul: + if s.read() { + continue + } + return false + } + break + } + return true +} + +func (s *Stream) Token() (interface{}, error) { + for { + c := s.char() + switch c { + case ' ', '\n', '\r', '\t': + s.cursor++ + case '{', '[', ']', '}': + s.cursor++ + return json.Delim(c), nil + case ',', ':': + s.cursor++ + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + bytes := floatBytes(s) + str := *(*string)(unsafe.Pointer(&bytes)) + if s.UseNumber { + return json.Number(str), nil + } + f64, err := strconv.ParseFloat(str, 64) + if err != nil { + return nil, err + } + return f64, nil + case '"': + bytes, err := stringBytes(s) + if err != nil { + return nil, err + } + return string(bytes), nil + case 't': + if err := trueBytes(s); err != nil { + return nil, err + } + return true, nil + case 'f': + if err := falseBytes(s); err != nil { + return nil, err + } + return false, nil + case 'n': + if err := nullBytes(s); err != nil { + return nil, err + } + return nil, nil + case nul: + if s.read() { + continue + } + goto END + default: + return nil, errors.ErrInvalidCharacter(s.char(), "token", s.totalOffset()) + } + } +END: + return nil, io.EOF +} + +func (s *Stream) reset() { + s.offset += s.cursor + s.buf = s.buf[s.cursor:] + s.length -= s.cursor + s.cursor = 0 +} + +func (s *Stream) readBuf() []byte { + if s.filledBuffer { + s.bufSize *= 2 + remainBuf := s.buf + s.buf = make([]byte, s.bufSize) + copy(s.buf, remainBuf) + } + remainLen := s.length - s.cursor + remainNotNulCharNum := int64(0) + for i := int64(0); i < remainLen; i++ { + if s.buf[s.cursor+i] == nul { + break + } + remainNotNulCharNum++ + } + s.length = s.cursor + remainNotNulCharNum + return s.buf[s.cursor+remainNotNulCharNum:] +} + +func (s *Stream) read() bool { + if s.allRead { + return false + } + buf := s.readBuf() + last := len(buf) - 1 + buf[last] = nul + n, err := s.r.Read(buf[:last]) + s.length += int64(n) + if n == last { + s.filledBuffer = true + } else { + s.filledBuffer = false + } + if err == io.EOF { + s.allRead = true + } else if err != nil { + return false + } + return true +} + +func (s *Stream) skipWhiteSpace() byte { + p := s.bufptr() +LOOP: + c := char(p, s.cursor) + switch c { + case ' ', '\n', '\t', '\r': + s.cursor++ + goto LOOP + case nul: + if s.read() { + p = s.bufptr() + goto LOOP + } + } + return c +} + +func (s *Stream) skipObject(depth int64) error { + braceCount := 1 + _, cursor, p := s.stat() + for { + switch char(p, cursor) { + case '{': + braceCount++ + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + case '}': + braceCount-- + depth-- + if braceCount == 0 { + s.cursor = cursor + 1 + return nil + } + case '[': + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + case ']': + depth-- + case '"': + for { + cursor++ + switch char(p, cursor) { + case '\\': + cursor++ + if char(p, cursor) == nul { + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + case '"': + goto SWITCH_OUT + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.statForRetry() + continue + } + return errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + } + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return errors.ErrUnexpectedEndOfJSON("object of object", cursor) + } + SWITCH_OUT: + cursor++ + } +} + +func (s *Stream) skipArray(depth int64) error { + bracketCount := 1 + _, cursor, p := s.stat() + for { + switch char(p, cursor) { + case '[': + bracketCount++ + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + case ']': + bracketCount-- + depth-- + if bracketCount == 0 { + s.cursor = cursor + 1 + return nil + } + case '{': + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + case '}': + depth-- + case '"': + for { + cursor++ + switch char(p, cursor) { + case '\\': + cursor++ + if char(p, cursor) == nul { + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + case '"': + goto SWITCH_OUT + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.statForRetry() + continue + } + return errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + } + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return errors.ErrUnexpectedEndOfJSON("array of object", cursor) + } + SWITCH_OUT: + cursor++ + } +} + +func (s *Stream) skipValue(depth int64) error { + _, cursor, p := s.stat() + for { + switch char(p, cursor) { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return errors.ErrUnexpectedEndOfJSON("value of object", s.totalOffset()) + case '{': + s.cursor = cursor + 1 + return s.skipObject(depth + 1) + case '[': + s.cursor = cursor + 1 + return s.skipArray(depth + 1) + case '"': + for { + cursor++ + switch char(p, cursor) { + case '\\': + cursor++ + if char(p, cursor) == nul { + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return errors.ErrUnexpectedEndOfJSON("value of string", s.totalOffset()) + } + case '"': + s.cursor = cursor + 1 + return nil + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.statForRetry() + continue + } + return errors.ErrUnexpectedEndOfJSON("value of string", s.totalOffset()) + } + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + for { + cursor++ + c := char(p, cursor) + if floatTable[c] { + continue + } else if c == nul { + if s.read() { + _, cursor, p = s.stat() + continue + } + } + s.cursor = cursor + return nil + } + case 't': + s.cursor = cursor + if err := trueBytes(s); err != nil { + return err + } + return nil + case 'f': + s.cursor = cursor + if err := falseBytes(s); err != nil { + return err + } + return nil + case 'n': + s.cursor = cursor + if err := nullBytes(s); err != nil { + return err + } + return nil + } + cursor++ + } +} + +func nullBytes(s *Stream) error { + // current cursor's character is 'n' + s.cursor++ + if s.char() != 'u' { + if err := retryReadNull(s); err != nil { + return err + } + } + s.cursor++ + if s.char() != 'l' { + if err := retryReadNull(s); err != nil { + return err + } + } + s.cursor++ + if s.char() != 'l' { + if err := retryReadNull(s); err != nil { + return err + } + } + s.cursor++ + return nil +} + +func retryReadNull(s *Stream) error { + if s.char() == nul && s.read() { + return nil + } + return errors.ErrInvalidCharacter(s.char(), "null", s.totalOffset()) +} + +func trueBytes(s *Stream) error { + // current cursor's character is 't' + s.cursor++ + if s.char() != 'r' { + if err := retryReadTrue(s); err != nil { + return err + } + } + s.cursor++ + if s.char() != 'u' { + if err := retryReadTrue(s); err != nil { + return err + } + } + s.cursor++ + if s.char() != 'e' { + if err := retryReadTrue(s); err != nil { + return err + } + } + s.cursor++ + return nil +} + +func retryReadTrue(s *Stream) error { + if s.char() == nul && s.read() { + return nil + } + return errors.ErrInvalidCharacter(s.char(), "bool(true)", s.totalOffset()) +} + +func falseBytes(s *Stream) error { + // current cursor's character is 'f' + s.cursor++ + if s.char() != 'a' { + if err := retryReadFalse(s); err != nil { + return err + } + } + s.cursor++ + if s.char() != 'l' { + if err := retryReadFalse(s); err != nil { + return err + } + } + s.cursor++ + if s.char() != 's' { + if err := retryReadFalse(s); err != nil { + return err + } + } + s.cursor++ + if s.char() != 'e' { + if err := retryReadFalse(s); err != nil { + return err + } + } + s.cursor++ + return nil +} + +func retryReadFalse(s *Stream) error { + if s.char() == nul && s.read() { + return nil + } + return errors.ErrInvalidCharacter(s.char(), "bool(false)", s.totalOffset()) +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/string.go b/vendor/github.com/goccy/go-json/internal/decoder/string.go new file mode 100644 index 000000000..32602c908 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/string.go @@ -0,0 +1,452 @@ +package decoder + +import ( + "bytes" + "fmt" + "reflect" + "unicode" + "unicode/utf16" + "unicode/utf8" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +type stringDecoder struct { + structName string + fieldName string +} + +func newStringDecoder(structName, fieldName string) *stringDecoder { + return &stringDecoder{ + structName: structName, + fieldName: fieldName, + } +} + +func (d *stringDecoder) errUnmarshalType(typeName string, offset int64) *errors.UnmarshalTypeError { + return &errors.UnmarshalTypeError{ + Value: typeName, + Type: reflect.TypeOf(""), + Offset: offset, + Struct: d.structName, + Field: d.fieldName, + } +} + +func (d *stringDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + bytes, err := d.decodeStreamByte(s) + if err != nil { + return err + } + if bytes == nil { + return nil + } + **(**string)(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&bytes)) + s.reset() + return nil +} + +func (d *stringDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + bytes, c, err := d.decodeByte(ctx.Buf, cursor) + if err != nil { + return 0, err + } + if bytes == nil { + return c, nil + } + cursor = c + **(**string)(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&bytes)) + return cursor, nil +} + +func (d *stringDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + bytes, c, err := d.decodeByte(ctx.Buf, cursor) + if err != nil { + return nil, 0, err + } + if bytes == nil { + return [][]byte{nullbytes}, c, nil + } + return [][]byte{bytes}, c, nil +} + +var ( + hexToInt = [256]int{ + '0': 0, + '1': 1, + '2': 2, + '3': 3, + '4': 4, + '5': 5, + '6': 6, + '7': 7, + '8': 8, + '9': 9, + 'A': 10, + 'B': 11, + 'C': 12, + 'D': 13, + 'E': 14, + 'F': 15, + 'a': 10, + 'b': 11, + 'c': 12, + 'd': 13, + 'e': 14, + 'f': 15, + } +) + +func unicodeToRune(code []byte) rune { + var r rune + for i := 0; i < len(code); i++ { + r = r*16 + rune(hexToInt[code[i]]) + } + return r +} + +func readAtLeast(s *Stream, n int64, p *unsafe.Pointer) bool { + for s.cursor+n >= s.length { + if !s.read() { + return false + } + *p = s.bufptr() + } + return true +} + +func decodeUnicodeRune(s *Stream, p unsafe.Pointer) (rune, int64, unsafe.Pointer, error) { + const defaultOffset = 5 + const surrogateOffset = 11 + + if !readAtLeast(s, defaultOffset, &p) { + return rune(0), 0, nil, errors.ErrInvalidCharacter(s.char(), "escaped string", s.totalOffset()) + } + + r := unicodeToRune(s.buf[s.cursor+1 : s.cursor+defaultOffset]) + if utf16.IsSurrogate(r) { + if !readAtLeast(s, surrogateOffset, &p) { + return unicode.ReplacementChar, defaultOffset, p, nil + } + if s.buf[s.cursor+defaultOffset] != '\\' || s.buf[s.cursor+defaultOffset+1] != 'u' { + return unicode.ReplacementChar, defaultOffset, p, nil + } + r2 := unicodeToRune(s.buf[s.cursor+defaultOffset+2 : s.cursor+surrogateOffset]) + if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar { + return r, surrogateOffset, p, nil + } + } + return r, defaultOffset, p, nil +} + +func decodeUnicode(s *Stream, p unsafe.Pointer) (unsafe.Pointer, error) { + const backSlashAndULen = 2 // length of \u + + r, offset, pp, err := decodeUnicodeRune(s, p) + if err != nil { + return nil, err + } + unicode := []byte(string(r)) + unicodeLen := int64(len(unicode)) + s.buf = append(append(s.buf[:s.cursor-1], unicode...), s.buf[s.cursor+offset:]...) + unicodeOrgLen := offset - 1 + s.length = s.length - (backSlashAndULen + (unicodeOrgLen - unicodeLen)) + s.cursor = s.cursor - backSlashAndULen + unicodeLen + return pp, nil +} + +func decodeEscapeString(s *Stream, p unsafe.Pointer) (unsafe.Pointer, error) { + s.cursor++ +RETRY: + switch s.buf[s.cursor] { + case '"': + s.buf[s.cursor] = '"' + case '\\': + s.buf[s.cursor] = '\\' + case '/': + s.buf[s.cursor] = '/' + case 'b': + s.buf[s.cursor] = '\b' + case 'f': + s.buf[s.cursor] = '\f' + case 'n': + s.buf[s.cursor] = '\n' + case 'r': + s.buf[s.cursor] = '\r' + case 't': + s.buf[s.cursor] = '\t' + case 'u': + return decodeUnicode(s, p) + case nul: + if !s.read() { + return nil, errors.ErrInvalidCharacter(s.char(), "escaped string", s.totalOffset()) + } + p = s.bufptr() + goto RETRY + default: + return nil, errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + } + s.buf = append(s.buf[:s.cursor-1], s.buf[s.cursor:]...) + s.length-- + s.cursor-- + p = s.bufptr() + return p, nil +} + +var ( + runeErrBytes = []byte(string(utf8.RuneError)) + runeErrBytesLen = int64(len(runeErrBytes)) +) + +func stringBytes(s *Stream) ([]byte, error) { + _, cursor, p := s.stat() + cursor++ // skip double quote char + start := cursor + for { + switch char(p, cursor) { + case '\\': + s.cursor = cursor + pp, err := decodeEscapeString(s, p) + if err != nil { + return nil, err + } + p = pp + cursor = s.cursor + case '"': + literal := s.buf[start:cursor] + cursor++ + s.cursor = cursor + return literal, nil + case + // 0x00 is nul, 0x5c is '\\', 0x22 is '"' . + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, // 0x00-0x0F + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, // 0x10-0x1F + 0x20, 0x21 /*0x22,*/, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, // 0x20-0x2F + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, // 0x30-0x3F + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, // 0x40-0x4F + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B /*0x5C,*/, 0x5D, 0x5E, 0x5F, // 0x50-0x5F + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, // 0x60-0x6F + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F: // 0x70-0x7F + // character is ASCII. skip to next char + case + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, // 0x80-0x8F + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, // 0x90-0x9F + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, // 0xA0-0xAF + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, // 0xB0-0xBF + 0xC0, 0xC1, // 0xC0-0xC1 + 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF: // 0xF5-0xFE + // character is invalid + s.buf = append(append(append([]byte{}, s.buf[:cursor]...), runeErrBytes...), s.buf[cursor+1:]...) + _, _, p = s.stat() + cursor += runeErrBytesLen + s.length += runeErrBytesLen + continue + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + goto ERROR + case 0xEF: + // RuneError is {0xEF, 0xBF, 0xBD} + if s.buf[cursor+1] == 0xBF && s.buf[cursor+2] == 0xBD { + // found RuneError: skip + cursor += 2 + break + } + fallthrough + default: + // multi bytes character + if !utf8.FullRune(s.buf[cursor : len(s.buf)-1]) { + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + goto ERROR + } + r, size := utf8.DecodeRune(s.buf[cursor:]) + if r == utf8.RuneError { + s.buf = append(append(append([]byte{}, s.buf[:cursor]...), runeErrBytes...), s.buf[cursor+1:]...) + cursor += runeErrBytesLen + s.length += runeErrBytesLen + _, _, p = s.stat() + } else { + cursor += int64(size) + } + continue + } + cursor++ + } +ERROR: + return nil, errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) +} + +func (d *stringDecoder) decodeStreamByte(s *Stream) ([]byte, error) { + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + s.cursor++ + continue + case '[': + return nil, d.errUnmarshalType("array", s.totalOffset()) + case '{': + return nil, d.errUnmarshalType("object", s.totalOffset()) + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return nil, d.errUnmarshalType("number", s.totalOffset()) + case '"': + return stringBytes(s) + case 'n': + if err := nullBytes(s); err != nil { + return nil, err + } + return nil, nil + case nul: + if s.read() { + continue + } + } + break + } + return nil, errors.ErrInvalidBeginningOfValue(s.char(), s.totalOffset()) +} + +func (d *stringDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) { + for { + switch buf[cursor] { + case ' ', '\n', '\t', '\r': + cursor++ + case '[': + return nil, 0, d.errUnmarshalType("array", cursor) + case '{': + return nil, 0, d.errUnmarshalType("object", cursor) + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return nil, 0, d.errUnmarshalType("number", cursor) + case '"': + cursor++ + start := cursor + b := (*sliceHeader)(unsafe.Pointer(&buf)).data + escaped := 0 + for { + switch char(b, cursor) { + case '\\': + escaped++ + cursor++ + switch char(b, cursor) { + case '"', '\\', '/', 'b', 'f', 'n', 'r', 't': + cursor++ + case 'u': + buflen := int64(len(buf)) + if cursor+5 >= buflen { + return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor) + } + for i := int64(1); i <= 4; i++ { + c := char(b, cursor+i) + if !(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')) { + return nil, 0, errors.ErrSyntax(fmt.Sprintf("json: invalid character %c in \\u hexadecimal character escape", c), cursor+i) + } + } + cursor += 5 + default: + return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor) + } + continue + case '"': + literal := buf[start:cursor] + if escaped > 0 { + literal = literal[:unescapeString(literal)] + } + cursor++ + return literal, cursor, nil + case nul: + return nil, 0, errors.ErrUnexpectedEndOfJSON("string", cursor) + } + cursor++ + } + case 'n': + if err := validateNull(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return nil, cursor, nil + default: + return nil, 0, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor) + } + } +} + +var unescapeMap = [256]byte{ + '"': '"', + '\\': '\\', + '/': '/', + 'b': '\b', + 'f': '\f', + 'n': '\n', + 'r': '\r', + 't': '\t', +} + +func unsafeAdd(ptr unsafe.Pointer, offset int) unsafe.Pointer { + return unsafe.Pointer(uintptr(ptr) + uintptr(offset)) +} + +func unescapeString(buf []byte) int { + p := (*sliceHeader)(unsafe.Pointer(&buf)).data + end := unsafeAdd(p, len(buf)) + src := unsafeAdd(p, bytes.IndexByte(buf, '\\')) + dst := src + for src != end { + c := char(src, 0) + if c == '\\' { + escapeChar := char(src, 1) + if escapeChar != 'u' { + *(*byte)(dst) = unescapeMap[escapeChar] + src = unsafeAdd(src, 2) + dst = unsafeAdd(dst, 1) + } else { + v1 := hexToInt[char(src, 2)] + v2 := hexToInt[char(src, 3)] + v3 := hexToInt[char(src, 4)] + v4 := hexToInt[char(src, 5)] + code := rune((v1 << 12) | (v2 << 8) | (v3 << 4) | v4) + if code >= 0xd800 && code < 0xdc00 && uintptr(unsafeAdd(src, 11)) < uintptr(end) { + if char(src, 6) == '\\' && char(src, 7) == 'u' { + v1 := hexToInt[char(src, 8)] + v2 := hexToInt[char(src, 9)] + v3 := hexToInt[char(src, 10)] + v4 := hexToInt[char(src, 11)] + lo := rune((v1 << 12) | (v2 << 8) | (v3 << 4) | v4) + if lo >= 0xdc00 && lo < 0xe000 { + code = (code-0xd800)<<10 | (lo - 0xdc00) + 0x10000 + src = unsafeAdd(src, 6) + } + } + } + var b [utf8.UTFMax]byte + n := utf8.EncodeRune(b[:], code) + switch n { + case 4: + *(*byte)(unsafeAdd(dst, 3)) = b[3] + fallthrough + case 3: + *(*byte)(unsafeAdd(dst, 2)) = b[2] + fallthrough + case 2: + *(*byte)(unsafeAdd(dst, 1)) = b[1] + fallthrough + case 1: + *(*byte)(unsafeAdd(dst, 0)) = b[0] + } + src = unsafeAdd(src, 6) + dst = unsafeAdd(dst, n) + } + } else { + *(*byte)(dst) = c + src = unsafeAdd(src, 1) + dst = unsafeAdd(dst, 1) + } + } + return int(uintptr(dst) - uintptr(p)) +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/struct.go b/vendor/github.com/goccy/go-json/internal/decoder/struct.go new file mode 100644 index 000000000..313da153b --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/struct.go @@ -0,0 +1,845 @@ +package decoder + +import ( + "fmt" + "math" + "math/bits" + "sort" + "strings" + "unicode" + "unicode/utf16" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +type structFieldSet struct { + dec Decoder + offset uintptr + isTaggedKey bool + fieldIdx int + key string + keyLen int64 + err error +} + +type structDecoder struct { + fieldMap map[string]*structFieldSet + fieldUniqueNameNum int + stringDecoder *stringDecoder + structName string + fieldName string + isTriedOptimize bool + keyBitmapUint8 [][256]uint8 + keyBitmapUint16 [][256]uint16 + sortedFieldSets []*structFieldSet + keyDecoder func(*structDecoder, []byte, int64) (int64, *structFieldSet, error) + keyStreamDecoder func(*structDecoder, *Stream) (*structFieldSet, string, error) +} + +var ( + largeToSmallTable [256]byte +) + +func init() { + for i := 0; i < 256; i++ { + c := i + if 'A' <= c && c <= 'Z' { + c += 'a' - 'A' + } + largeToSmallTable[i] = byte(c) + } +} + +func toASCIILower(s string) string { + b := []byte(s) + for i := range b { + b[i] = largeToSmallTable[b[i]] + } + return string(b) +} + +func newStructDecoder(structName, fieldName string, fieldMap map[string]*structFieldSet) *structDecoder { + return &structDecoder{ + fieldMap: fieldMap, + stringDecoder: newStringDecoder(structName, fieldName), + structName: structName, + fieldName: fieldName, + keyDecoder: decodeKey, + keyStreamDecoder: decodeKeyStream, + } +} + +const ( + allowOptimizeMaxKeyLen = 64 + allowOptimizeMaxFieldLen = 16 +) + +func (d *structDecoder) tryOptimize() { + fieldUniqueNameMap := map[string]int{} + fieldIdx := -1 + for k, v := range d.fieldMap { + lower := strings.ToLower(k) + idx, exists := fieldUniqueNameMap[lower] + if exists { + v.fieldIdx = idx + } else { + fieldIdx++ + v.fieldIdx = fieldIdx + } + fieldUniqueNameMap[lower] = fieldIdx + } + d.fieldUniqueNameNum = len(fieldUniqueNameMap) + + if d.isTriedOptimize { + return + } + fieldMap := map[string]*structFieldSet{} + conflicted := map[string]struct{}{} + for k, v := range d.fieldMap { + key := strings.ToLower(k) + if key != k { + if key != toASCIILower(k) { + d.isTriedOptimize = true + return + } + // already exists same key (e.g. Hello and HELLO has same lower case key + if _, exists := conflicted[key]; exists { + d.isTriedOptimize = true + return + } + conflicted[key] = struct{}{} + } + if field, exists := fieldMap[key]; exists { + if field != v { + d.isTriedOptimize = true + return + } + } + fieldMap[key] = v + } + + if len(fieldMap) > allowOptimizeMaxFieldLen { + d.isTriedOptimize = true + return + } + + var maxKeyLen int + sortedKeys := []string{} + for key := range fieldMap { + keyLen := len(key) + if keyLen > allowOptimizeMaxKeyLen { + d.isTriedOptimize = true + return + } + if maxKeyLen < keyLen { + maxKeyLen = keyLen + } + sortedKeys = append(sortedKeys, key) + } + sort.Strings(sortedKeys) + + // By allocating one extra capacity than `maxKeyLen`, + // it is possible to avoid the process of comparing the index of the key with the length of the bitmap each time. + bitmapLen := maxKeyLen + 1 + if len(sortedKeys) <= 8 { + keyBitmap := make([][256]uint8, bitmapLen) + for i, key := range sortedKeys { + for j := 0; j < len(key); j++ { + c := key[j] + keyBitmap[j][c] |= (1 << uint(i)) + } + d.sortedFieldSets = append(d.sortedFieldSets, fieldMap[key]) + } + d.keyBitmapUint8 = keyBitmap + d.keyDecoder = decodeKeyByBitmapUint8 + d.keyStreamDecoder = decodeKeyByBitmapUint8Stream + } else { + keyBitmap := make([][256]uint16, bitmapLen) + for i, key := range sortedKeys { + for j := 0; j < len(key); j++ { + c := key[j] + keyBitmap[j][c] |= (1 << uint(i)) + } + d.sortedFieldSets = append(d.sortedFieldSets, fieldMap[key]) + } + d.keyBitmapUint16 = keyBitmap + d.keyDecoder = decodeKeyByBitmapUint16 + d.keyStreamDecoder = decodeKeyByBitmapUint16Stream + } +} + +// decode from '\uXXXX' +func decodeKeyCharByUnicodeRune(buf []byte, cursor int64) ([]byte, int64, error) { + const defaultOffset = 4 + const surrogateOffset = 6 + + if cursor+defaultOffset >= int64(len(buf)) { + return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor) + } + + r := unicodeToRune(buf[cursor : cursor+defaultOffset]) + if utf16.IsSurrogate(r) { + cursor += defaultOffset + if cursor+surrogateOffset >= int64(len(buf)) || buf[cursor] != '\\' || buf[cursor+1] != 'u' { + return []byte(string(unicode.ReplacementChar)), cursor + defaultOffset - 1, nil + } + cursor += 2 + r2 := unicodeToRune(buf[cursor : cursor+defaultOffset]) + if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar { + return []byte(string(r)), cursor + defaultOffset - 1, nil + } + } + return []byte(string(r)), cursor + defaultOffset - 1, nil +} + +func decodeKeyCharByEscapedChar(buf []byte, cursor int64) ([]byte, int64, error) { + c := buf[cursor] + cursor++ + switch c { + case '"': + return []byte{'"'}, cursor, nil + case '\\': + return []byte{'\\'}, cursor, nil + case '/': + return []byte{'/'}, cursor, nil + case 'b': + return []byte{'\b'}, cursor, nil + case 'f': + return []byte{'\f'}, cursor, nil + case 'n': + return []byte{'\n'}, cursor, nil + case 'r': + return []byte{'\r'}, cursor, nil + case 't': + return []byte{'\t'}, cursor, nil + case 'u': + return decodeKeyCharByUnicodeRune(buf, cursor) + } + return nil, cursor, nil +} + +func decodeKeyByBitmapUint8(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) { + var ( + curBit uint8 = math.MaxUint8 + ) + b := (*sliceHeader)(unsafe.Pointer(&buf)).data + for { + switch char(b, cursor) { + case ' ', '\n', '\t', '\r': + cursor++ + case '"': + cursor++ + c := char(b, cursor) + switch c { + case '"': + cursor++ + return cursor, nil, nil + case nul: + return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor) + } + keyIdx := 0 + bitmap := d.keyBitmapUint8 + start := cursor + for { + c := char(b, cursor) + switch c { + case '"': + fieldSetIndex := bits.TrailingZeros8(curBit) + field := d.sortedFieldSets[fieldSetIndex] + keyLen := cursor - start + cursor++ + if keyLen < field.keyLen { + // early match + return cursor, nil, nil + } + return cursor, field, nil + case nul: + return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor) + case '\\': + cursor++ + chars, nextCursor, err := decodeKeyCharByEscapedChar(buf, cursor) + if err != nil { + return 0, nil, err + } + for _, c := range chars { + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + return decodeKeyNotFound(b, cursor) + } + keyIdx++ + } + cursor = nextCursor + default: + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + return decodeKeyNotFound(b, cursor) + } + keyIdx++ + } + cursor++ + } + default: + return cursor, nil, errors.ErrInvalidBeginningOfValue(char(b, cursor), cursor) + } + } +} + +func decodeKeyByBitmapUint16(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) { + var ( + curBit uint16 = math.MaxUint16 + ) + b := (*sliceHeader)(unsafe.Pointer(&buf)).data + for { + switch char(b, cursor) { + case ' ', '\n', '\t', '\r': + cursor++ + case '"': + cursor++ + c := char(b, cursor) + switch c { + case '"': + cursor++ + return cursor, nil, nil + case nul: + return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor) + } + keyIdx := 0 + bitmap := d.keyBitmapUint16 + start := cursor + for { + c := char(b, cursor) + switch c { + case '"': + fieldSetIndex := bits.TrailingZeros16(curBit) + field := d.sortedFieldSets[fieldSetIndex] + keyLen := cursor - start + cursor++ + if keyLen < field.keyLen { + // early match + return cursor, nil, nil + } + return cursor, field, nil + case nul: + return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor) + case '\\': + cursor++ + chars, nextCursor, err := decodeKeyCharByEscapedChar(buf, cursor) + if err != nil { + return 0, nil, err + } + for _, c := range chars { + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + return decodeKeyNotFound(b, cursor) + } + keyIdx++ + } + cursor = nextCursor + default: + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + return decodeKeyNotFound(b, cursor) + } + keyIdx++ + } + cursor++ + } + default: + return cursor, nil, errors.ErrInvalidBeginningOfValue(char(b, cursor), cursor) + } + } +} + +func decodeKeyNotFound(b unsafe.Pointer, cursor int64) (int64, *structFieldSet, error) { + for { + cursor++ + switch char(b, cursor) { + case '"': + cursor++ + return cursor, nil, nil + case '\\': + cursor++ + if char(b, cursor) == nul { + return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor) + } + case nul: + return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor) + } + } +} + +func decodeKey(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) { + key, c, err := d.stringDecoder.decodeByte(buf, cursor) + if err != nil { + return 0, nil, err + } + cursor = c + k := *(*string)(unsafe.Pointer(&key)) + field, exists := d.fieldMap[k] + if !exists { + return cursor, nil, nil + } + return cursor, field, nil +} + +func decodeKeyByBitmapUint8Stream(d *structDecoder, s *Stream) (*structFieldSet, string, error) { + var ( + curBit uint8 = math.MaxUint8 + ) + _, cursor, p := s.stat() + for { + switch char(p, cursor) { + case ' ', '\n', '\t', '\r': + cursor++ + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return nil, "", errors.ErrInvalidBeginningOfValue(char(p, cursor), s.totalOffset()) + case '"': + cursor++ + FIRST_CHAR: + start := cursor + switch char(p, cursor) { + case '"': + cursor++ + s.cursor = cursor + return nil, "", nil + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + goto FIRST_CHAR + } + return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + } + keyIdx := 0 + bitmap := d.keyBitmapUint8 + for { + c := char(p, cursor) + switch c { + case '"': + fieldSetIndex := bits.TrailingZeros8(curBit) + field := d.sortedFieldSets[fieldSetIndex] + keyLen := cursor - start + cursor++ + s.cursor = cursor + if keyLen < field.keyLen { + // early match + return nil, field.key, nil + } + return field, field.key, nil + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + case '\\': + s.cursor = cursor + 1 // skip '\' char + chars, err := decodeKeyCharByEscapeCharStream(s) + if err != nil { + return nil, "", err + } + cursor = s.cursor + for _, c := range chars { + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + s.cursor = cursor + return decodeKeyNotFoundStream(s, start) + } + keyIdx++ + } + default: + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + s.cursor = cursor + return decodeKeyNotFoundStream(s, start) + } + keyIdx++ + } + cursor++ + } + default: + return nil, "", errors.ErrInvalidBeginningOfValue(char(p, cursor), s.totalOffset()) + } + } +} + +func decodeKeyByBitmapUint16Stream(d *structDecoder, s *Stream) (*structFieldSet, string, error) { + var ( + curBit uint16 = math.MaxUint16 + ) + _, cursor, p := s.stat() + for { + switch char(p, cursor) { + case ' ', '\n', '\t', '\r': + cursor++ + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return nil, "", errors.ErrInvalidBeginningOfValue(char(p, cursor), s.totalOffset()) + case '"': + cursor++ + FIRST_CHAR: + start := cursor + switch char(p, cursor) { + case '"': + cursor++ + s.cursor = cursor + return nil, "", nil + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + goto FIRST_CHAR + } + return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + } + keyIdx := 0 + bitmap := d.keyBitmapUint16 + for { + c := char(p, cursor) + switch c { + case '"': + fieldSetIndex := bits.TrailingZeros16(curBit) + field := d.sortedFieldSets[fieldSetIndex] + keyLen := cursor - start + cursor++ + s.cursor = cursor + if keyLen < field.keyLen { + // early match + return nil, field.key, nil + } + return field, field.key, nil + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + case '\\': + s.cursor = cursor + 1 // skip '\' char + chars, err := decodeKeyCharByEscapeCharStream(s) + if err != nil { + return nil, "", err + } + cursor = s.cursor + for _, c := range chars { + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + s.cursor = cursor + return decodeKeyNotFoundStream(s, start) + } + keyIdx++ + } + default: + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + s.cursor = cursor + return decodeKeyNotFoundStream(s, start) + } + keyIdx++ + } + cursor++ + } + default: + return nil, "", errors.ErrInvalidBeginningOfValue(char(p, cursor), s.totalOffset()) + } + } +} + +// decode from '\uXXXX' +func decodeKeyCharByUnicodeRuneStream(s *Stream) ([]byte, error) { + const defaultOffset = 4 + const surrogateOffset = 6 + + if s.cursor+defaultOffset >= s.length { + if !s.read() { + return nil, errors.ErrInvalidCharacter(s.char(), "escaped unicode char", s.totalOffset()) + } + } + + r := unicodeToRune(s.buf[s.cursor : s.cursor+defaultOffset]) + if utf16.IsSurrogate(r) { + s.cursor += defaultOffset + if s.cursor+surrogateOffset >= s.length { + s.read() + } + if s.cursor+surrogateOffset >= s.length || s.buf[s.cursor] != '\\' || s.buf[s.cursor+1] != 'u' { + s.cursor += defaultOffset - 1 + return []byte(string(unicode.ReplacementChar)), nil + } + r2 := unicodeToRune(s.buf[s.cursor+defaultOffset+2 : s.cursor+surrogateOffset]) + if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar { + s.cursor += defaultOffset - 1 + return []byte(string(r)), nil + } + } + s.cursor += defaultOffset - 1 + return []byte(string(r)), nil +} + +func decodeKeyCharByEscapeCharStream(s *Stream) ([]byte, error) { + c := s.buf[s.cursor] + s.cursor++ +RETRY: + switch c { + case '"': + return []byte{'"'}, nil + case '\\': + return []byte{'\\'}, nil + case '/': + return []byte{'/'}, nil + case 'b': + return []byte{'\b'}, nil + case 'f': + return []byte{'\f'}, nil + case 'n': + return []byte{'\n'}, nil + case 'r': + return []byte{'\r'}, nil + case 't': + return []byte{'\t'}, nil + case 'u': + return decodeKeyCharByUnicodeRuneStream(s) + case nul: + if !s.read() { + return nil, errors.ErrInvalidCharacter(s.char(), "escaped char", s.totalOffset()) + } + goto RETRY + default: + return nil, errors.ErrUnexpectedEndOfJSON("struct field", s.totalOffset()) + } +} + +func decodeKeyNotFoundStream(s *Stream, start int64) (*structFieldSet, string, error) { + buf, cursor, p := s.stat() + for { + cursor++ + switch char(p, cursor) { + case '"': + b := buf[start:cursor] + key := *(*string)(unsafe.Pointer(&b)) + cursor++ + s.cursor = cursor + return nil, key, nil + case '\\': + cursor++ + if char(p, cursor) == nul { + s.cursor = cursor + if !s.read() { + return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + } + buf, cursor, p = s.statForRetry() + } + case nul: + s.cursor = cursor + if !s.read() { + return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + } + buf, cursor, p = s.statForRetry() + } + } +} + +func decodeKeyStream(d *structDecoder, s *Stream) (*structFieldSet, string, error) { + key, err := d.stringDecoder.decodeStreamByte(s) + if err != nil { + return nil, "", err + } + k := *(*string)(unsafe.Pointer(&key)) + return d.fieldMap[k], k, nil +} + +func (d *structDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + + c := s.skipWhiteSpace() + switch c { + case 'n': + if err := nullBytes(s); err != nil { + return err + } + return nil + default: + if s.char() != '{' { + return errors.ErrInvalidBeginningOfValue(s.char(), s.totalOffset()) + } + } + s.cursor++ + if s.skipWhiteSpace() == '}' { + s.cursor++ + return nil + } + var ( + seenFields map[int]struct{} + seenFieldNum int + ) + firstWin := (s.Option.Flags & FirstWinOption) != 0 + if firstWin { + seenFields = make(map[int]struct{}, d.fieldUniqueNameNum) + } + for { + s.reset() + field, key, err := d.keyStreamDecoder(d, s) + if err != nil { + return err + } + if s.skipWhiteSpace() != ':' { + return errors.ErrExpected("colon after object key", s.totalOffset()) + } + s.cursor++ + if field != nil { + if field.err != nil { + return field.err + } + if firstWin { + if _, exists := seenFields[field.fieldIdx]; exists { + if err := s.skipValue(depth); err != nil { + return err + } + } else { + if err := field.dec.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+field.offset)); err != nil { + return err + } + seenFieldNum++ + if d.fieldUniqueNameNum <= seenFieldNum { + return s.skipObject(depth) + } + seenFields[field.fieldIdx] = struct{}{} + } + } else { + if err := field.dec.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+field.offset)); err != nil { + return err + } + } + } else if s.DisallowUnknownFields { + return fmt.Errorf("json: unknown field %q", key) + } else { + if err := s.skipValue(depth); err != nil { + return err + } + } + c := s.skipWhiteSpace() + if c == '}' { + s.cursor++ + return nil + } + if c != ',' { + return errors.ErrExpected("comma after object element", s.totalOffset()) + } + s.cursor++ + } +} + +func (d *structDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + buflen := int64(len(buf)) + cursor = skipWhiteSpace(buf, cursor) + b := (*sliceHeader)(unsafe.Pointer(&buf)).data + switch char(b, cursor) { + case 'n': + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + return cursor, nil + case '{': + default: + return 0, errors.ErrInvalidBeginningOfValue(char(b, cursor), cursor) + } + cursor++ + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == '}' { + cursor++ + return cursor, nil + } + var ( + seenFields map[int]struct{} + seenFieldNum int + ) + firstWin := (ctx.Option.Flags & FirstWinOption) != 0 + if firstWin { + seenFields = make(map[int]struct{}, d.fieldUniqueNameNum) + } + for { + c, field, err := d.keyDecoder(d, buf, cursor) + if err != nil { + return 0, err + } + cursor = skipWhiteSpace(buf, c) + if char(b, cursor) != ':' { + return 0, errors.ErrExpected("colon after object key", cursor) + } + cursor++ + if cursor >= buflen { + return 0, errors.ErrExpected("object value after colon", cursor) + } + if field != nil { + if field.err != nil { + return 0, field.err + } + if firstWin { + if _, exists := seenFields[field.fieldIdx]; exists { + c, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + cursor = c + } else { + c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset)) + if err != nil { + return 0, err + } + cursor = c + seenFieldNum++ + if d.fieldUniqueNameNum <= seenFieldNum { + return skipObject(buf, cursor, depth) + } + seenFields[field.fieldIdx] = struct{}{} + } + } else { + c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset)) + if err != nil { + return 0, err + } + cursor = c + } + } else { + c, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + cursor = c + } + cursor = skipWhiteSpace(buf, cursor) + if char(b, cursor) == '}' { + cursor++ + return cursor, nil + } + if char(b, cursor) != ',' { + return 0, errors.ErrExpected("comma after object element", cursor) + } + cursor++ + } +} + +func (d *structDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + return nil, 0, fmt.Errorf("json: struct decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/type.go b/vendor/github.com/goccy/go-json/internal/decoder/type.go new file mode 100644 index 000000000..beaf3ab86 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/type.go @@ -0,0 +1,30 @@ +package decoder + +import ( + "context" + "encoding" + "encoding/json" + "reflect" + "unsafe" +) + +type Decoder interface { + Decode(*RuntimeContext, int64, int64, unsafe.Pointer) (int64, error) + DecodePath(*RuntimeContext, int64, int64) ([][]byte, int64, error) + DecodeStream(*Stream, int64, unsafe.Pointer) error +} + +const ( + nul = '\000' + maxDecodeNestingDepth = 10000 +) + +type unmarshalerContext interface { + UnmarshalJSON(context.Context, []byte) error +} + +var ( + unmarshalJSONType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() + unmarshalJSONContextType = reflect.TypeOf((*unmarshalerContext)(nil)).Elem() + unmarshalTextType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() +) diff --git a/vendor/github.com/goccy/go-json/internal/decoder/uint.go b/vendor/github.com/goccy/go-json/internal/decoder/uint.go new file mode 100644 index 000000000..4131731b8 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/uint.go @@ -0,0 +1,194 @@ +package decoder + +import ( + "fmt" + "reflect" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type uintDecoder struct { + typ *runtime.Type + kind reflect.Kind + op func(unsafe.Pointer, uint64) + structName string + fieldName string +} + +func newUintDecoder(typ *runtime.Type, structName, fieldName string, op func(unsafe.Pointer, uint64)) *uintDecoder { + return &uintDecoder{ + typ: typ, + kind: typ.Kind(), + op: op, + structName: structName, + fieldName: fieldName, + } +} + +func (d *uintDecoder) typeError(buf []byte, offset int64) *errors.UnmarshalTypeError { + return &errors.UnmarshalTypeError{ + Value: fmt.Sprintf("number %s", string(buf)), + Type: runtime.RType2Type(d.typ), + Offset: offset, + } +} + +var ( + pow10u64 = [...]uint64{ + 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + } + pow10u64Len = len(pow10u64) +) + +func (d *uintDecoder) parseUint(b []byte) (uint64, error) { + maxDigit := len(b) + if maxDigit > pow10u64Len { + return 0, fmt.Errorf("invalid length of number") + } + sum := uint64(0) + for i := 0; i < maxDigit; i++ { + c := uint64(b[i]) - 48 + digitValue := pow10u64[maxDigit-i-1] + sum += c * digitValue + } + return sum, nil +} + +func (d *uintDecoder) decodeStreamByte(s *Stream) ([]byte, error) { + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + s.cursor++ + continue + case '0': + s.cursor++ + return numZeroBuf, nil + case '1', '2', '3', '4', '5', '6', '7', '8', '9': + start := s.cursor + for { + s.cursor++ + if numTable[s.char()] { + continue + } else if s.char() == nul { + if s.read() { + s.cursor-- // for retry current character + continue + } + } + break + } + num := s.buf[start:s.cursor] + return num, nil + case 'n': + if err := nullBytes(s); err != nil { + return nil, err + } + return nil, nil + case nul: + if s.read() { + continue + } + default: + return nil, d.typeError([]byte{s.char()}, s.totalOffset()) + } + break + } + return nil, errors.ErrUnexpectedEndOfJSON("number(unsigned integer)", s.totalOffset()) +} + +func (d *uintDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) { + for { + switch buf[cursor] { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case '0': + cursor++ + return numZeroBuf, cursor, nil + case '1', '2', '3', '4', '5', '6', '7', '8', '9': + start := cursor + cursor++ + for numTable[buf[cursor]] { + cursor++ + } + num := buf[start:cursor] + return num, cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return nil, cursor, nil + default: + return nil, 0, d.typeError([]byte{buf[cursor]}, cursor) + } + } +} + +func (d *uintDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + bytes, err := d.decodeStreamByte(s) + if err != nil { + return err + } + if bytes == nil { + return nil + } + u64, err := d.parseUint(bytes) + if err != nil { + return d.typeError(bytes, s.totalOffset()) + } + switch d.kind { + case reflect.Uint8: + if (1 << 8) <= u64 { + return d.typeError(bytes, s.totalOffset()) + } + case reflect.Uint16: + if (1 << 16) <= u64 { + return d.typeError(bytes, s.totalOffset()) + } + case reflect.Uint32: + if (1 << 32) <= u64 { + return d.typeError(bytes, s.totalOffset()) + } + } + d.op(p, u64) + return nil +} + +func (d *uintDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + bytes, c, err := d.decodeByte(ctx.Buf, cursor) + if err != nil { + return 0, err + } + if bytes == nil { + return c, nil + } + cursor = c + u64, err := d.parseUint(bytes) + if err != nil { + return 0, d.typeError(bytes, cursor) + } + switch d.kind { + case reflect.Uint8: + if (1 << 8) <= u64 { + return 0, d.typeError(bytes, cursor) + } + case reflect.Uint16: + if (1 << 16) <= u64 { + return 0, d.typeError(bytes, cursor) + } + case reflect.Uint32: + if (1 << 32) <= u64 { + return 0, d.typeError(bytes, cursor) + } + } + d.op(p, u64) + return cursor, nil +} + +func (d *uintDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + return nil, 0, fmt.Errorf("json: uint decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go new file mode 100644 index 000000000..4cd6dbd57 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go @@ -0,0 +1,104 @@ +package decoder + +import ( + "context" + "encoding/json" + "fmt" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type unmarshalJSONDecoder struct { + typ *runtime.Type + structName string + fieldName string +} + +func newUnmarshalJSONDecoder(typ *runtime.Type, structName, fieldName string) *unmarshalJSONDecoder { + return &unmarshalJSONDecoder{ + typ: typ, + structName: structName, + fieldName: fieldName, + } +} + +func (d *unmarshalJSONDecoder) annotateError(cursor int64, err error) { + switch e := err.(type) { + case *errors.UnmarshalTypeError: + e.Struct = d.structName + e.Field = d.fieldName + case *errors.SyntaxError: + e.Offset = cursor + } +} + +func (d *unmarshalJSONDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + s.skipWhiteSpace() + start := s.cursor + if err := s.skipValue(depth); err != nil { + return err + } + src := s.buf[start:s.cursor] + dst := make([]byte, len(src)) + copy(dst, src) + + v := *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: d.typ, + ptr: p, + })) + switch v := v.(type) { + case unmarshalerContext: + var ctx context.Context + if (s.Option.Flags & ContextOption) != 0 { + ctx = s.Option.Context + } else { + ctx = context.Background() + } + if err := v.UnmarshalJSON(ctx, dst); err != nil { + d.annotateError(s.cursor, err) + return err + } + case json.Unmarshaler: + if err := v.UnmarshalJSON(dst); err != nil { + d.annotateError(s.cursor, err) + return err + } + } + return nil +} + +func (d *unmarshalJSONDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + cursor = skipWhiteSpace(buf, cursor) + start := cursor + end, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + src := buf[start:end] + dst := make([]byte, len(src)) + copy(dst, src) + + v := *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: d.typ, + ptr: p, + })) + if (ctx.Option.Flags & ContextOption) != 0 { + if err := v.(unmarshalerContext).UnmarshalJSON(ctx.Option.Context, dst); err != nil { + d.annotateError(cursor, err) + return 0, err + } + } else { + if err := v.(json.Unmarshaler).UnmarshalJSON(dst); err != nil { + d.annotateError(cursor, err) + return 0, err + } + } + return end, nil +} + +func (d *unmarshalJSONDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + return nil, 0, fmt.Errorf("json: unmarshal json decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go new file mode 100644 index 000000000..6d37993f0 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go @@ -0,0 +1,285 @@ +package decoder + +import ( + "bytes" + "encoding" + "fmt" + "unicode" + "unicode/utf16" + "unicode/utf8" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type unmarshalTextDecoder struct { + typ *runtime.Type + structName string + fieldName string +} + +func newUnmarshalTextDecoder(typ *runtime.Type, structName, fieldName string) *unmarshalTextDecoder { + return &unmarshalTextDecoder{ + typ: typ, + structName: structName, + fieldName: fieldName, + } +} + +func (d *unmarshalTextDecoder) annotateError(cursor int64, err error) { + switch e := err.(type) { + case *errors.UnmarshalTypeError: + e.Struct = d.structName + e.Field = d.fieldName + case *errors.SyntaxError: + e.Offset = cursor + } +} + +var ( + nullbytes = []byte(`null`) +) + +func (d *unmarshalTextDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + s.skipWhiteSpace() + start := s.cursor + if err := s.skipValue(depth); err != nil { + return err + } + src := s.buf[start:s.cursor] + if len(src) > 0 { + switch src[0] { + case '[': + return &errors.UnmarshalTypeError{ + Value: "array", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + case '{': + return &errors.UnmarshalTypeError{ + Value: "object", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return &errors.UnmarshalTypeError{ + Value: "number", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + case 'n': + if bytes.Equal(src, nullbytes) { + *(*unsafe.Pointer)(p) = nil + return nil + } + } + } + dst := make([]byte, len(src)) + copy(dst, src) + + if b, ok := unquoteBytes(dst); ok { + dst = b + } + v := *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: d.typ, + ptr: p, + })) + if err := v.(encoding.TextUnmarshaler).UnmarshalText(dst); err != nil { + d.annotateError(s.cursor, err) + return err + } + return nil +} + +func (d *unmarshalTextDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + cursor = skipWhiteSpace(buf, cursor) + start := cursor + end, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + src := buf[start:end] + if len(src) > 0 { + switch src[0] { + case '[': + return 0, &errors.UnmarshalTypeError{ + Value: "array", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + case '{': + return 0, &errors.UnmarshalTypeError{ + Value: "object", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return 0, &errors.UnmarshalTypeError{ + Value: "number", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + case 'n': + if bytes.Equal(src, nullbytes) { + *(*unsafe.Pointer)(p) = nil + return end, nil + } + } + } + + if s, ok := unquoteBytes(src); ok { + src = s + } + v := *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: d.typ, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) + if err := v.(encoding.TextUnmarshaler).UnmarshalText(src); err != nil { + d.annotateError(cursor, err) + return 0, err + } + return end, nil +} + +func (d *unmarshalTextDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + return nil, 0, fmt.Errorf("json: unmarshal text decoder does not support decode path") +} + +func unquoteBytes(s []byte) (t []byte, ok bool) { + length := len(s) + if length < 2 || s[0] != '"' || s[length-1] != '"' { + return + } + s = s[1 : length-1] + length -= 2 + + // Check for unusual characters. If there are none, + // then no unquoting is needed, so return a slice of the + // original bytes. + r := 0 + for r < length { + c := s[r] + if c == '\\' || c == '"' || c < ' ' { + break + } + if c < utf8.RuneSelf { + r++ + continue + } + rr, size := utf8.DecodeRune(s[r:]) + if rr == utf8.RuneError && size == 1 { + break + } + r += size + } + if r == length { + return s, true + } + + b := make([]byte, length+2*utf8.UTFMax) + w := copy(b, s[0:r]) + for r < length { + // Out of room? Can only happen if s is full of + // malformed UTF-8 and we're replacing each + // byte with RuneError. + if w >= len(b)-2*utf8.UTFMax { + nb := make([]byte, (len(b)+utf8.UTFMax)*2) + copy(nb, b[0:w]) + b = nb + } + switch c := s[r]; { + case c == '\\': + r++ + if r >= length { + return + } + switch s[r] { + default: + return + case '"', '\\', '/', '\'': + b[w] = s[r] + r++ + w++ + case 'b': + b[w] = '\b' + r++ + w++ + case 'f': + b[w] = '\f' + r++ + w++ + case 'n': + b[w] = '\n' + r++ + w++ + case 'r': + b[w] = '\r' + r++ + w++ + case 't': + b[w] = '\t' + r++ + w++ + case 'u': + r-- + rr := getu4(s[r:]) + if rr < 0 { + return + } + r += 6 + if utf16.IsSurrogate(rr) { + rr1 := getu4(s[r:]) + if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar { + // A valid pair; consume. + r += 6 + w += utf8.EncodeRune(b[w:], dec) + break + } + // Invalid surrogate; fall back to replacement rune. + rr = unicode.ReplacementChar + } + w += utf8.EncodeRune(b[w:], rr) + } + + // Quote, control characters are invalid. + case c == '"', c < ' ': + return + + // ASCII + case c < utf8.RuneSelf: + b[w] = c + r++ + w++ + + // Coerce to well-formed UTF-8. + default: + rr, size := utf8.DecodeRune(s[r:]) + r += size + w += utf8.EncodeRune(b[w:], rr) + } + } + return b[0:w], true +} + +func getu4(s []byte) rune { + if len(s) < 6 || s[0] != '\\' || s[1] != 'u' { + return -1 + } + var r rune + for _, c := range s[2:6] { + switch { + case '0' <= c && c <= '9': + c = c - '0' + case 'a' <= c && c <= 'f': + c = c - 'a' + 10 + case 'A' <= c && c <= 'F': + c = c - 'A' + 10 + default: + return -1 + } + r = r*16 + rune(c) + } + return r +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go b/vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go new file mode 100644 index 000000000..0c4e2e6ea --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go @@ -0,0 +1,73 @@ +package decoder + +import ( + "fmt" + "reflect" + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +type wrappedStringDecoder struct { + typ *runtime.Type + dec Decoder + stringDecoder *stringDecoder + structName string + fieldName string + isPtrType bool +} + +func newWrappedStringDecoder(typ *runtime.Type, dec Decoder, structName, fieldName string) *wrappedStringDecoder { + return &wrappedStringDecoder{ + typ: typ, + dec: dec, + stringDecoder: newStringDecoder(structName, fieldName), + structName: structName, + fieldName: fieldName, + isPtrType: typ.Kind() == reflect.Ptr, + } +} + +func (d *wrappedStringDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + bytes, err := d.stringDecoder.decodeStreamByte(s) + if err != nil { + return err + } + if bytes == nil { + if d.isPtrType { + *(*unsafe.Pointer)(p) = nil + } + return nil + } + b := make([]byte, len(bytes)+1) + copy(b, bytes) + if _, err := d.dec.Decode(&RuntimeContext{Buf: b}, 0, depth, p); err != nil { + return err + } + return nil +} + +func (d *wrappedStringDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + bytes, c, err := d.stringDecoder.decodeByte(ctx.Buf, cursor) + if err != nil { + return 0, err + } + if bytes == nil { + if d.isPtrType { + *(*unsafe.Pointer)(p) = nil + } + return c, nil + } + bytes = append(bytes, nul) + oldBuf := ctx.Buf + ctx.Buf = bytes + if _, err := d.dec.Decode(ctx, 0, depth, p); err != nil { + return 0, err + } + ctx.Buf = oldBuf + return c, nil +} + +func (d *wrappedStringDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { + return nil, 0, fmt.Errorf("json: wrapped string decoder does not support decode path") +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/code.go b/vendor/github.com/goccy/go-json/internal/encoder/code.go new file mode 100644 index 000000000..5b08faefc --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/code.go @@ -0,0 +1,1023 @@ +package encoder + +import ( + "fmt" + "reflect" + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +type Code interface { + Kind() CodeKind + ToOpcode(*compileContext) Opcodes + Filter(*FieldQuery) Code +} + +type AnonymousCode interface { + ToAnonymousOpcode(*compileContext) Opcodes +} + +type Opcodes []*Opcode + +func (o Opcodes) First() *Opcode { + if len(o) == 0 { + return nil + } + return o[0] +} + +func (o Opcodes) Last() *Opcode { + if len(o) == 0 { + return nil + } + return o[len(o)-1] +} + +func (o Opcodes) Add(codes ...*Opcode) Opcodes { + return append(o, codes...) +} + +type CodeKind int + +const ( + CodeKindInterface CodeKind = iota + CodeKindPtr + CodeKindInt + CodeKindUint + CodeKindFloat + CodeKindString + CodeKindBool + CodeKindStruct + CodeKindMap + CodeKindSlice + CodeKindArray + CodeKindBytes + CodeKindMarshalJSON + CodeKindMarshalText + CodeKindRecursive +) + +type IntCode struct { + typ *runtime.Type + bitSize uint8 + isString bool + isPtr bool +} + +func (c *IntCode) Kind() CodeKind { + return CodeKindInt +} + +func (c *IntCode) ToOpcode(ctx *compileContext) Opcodes { + var code *Opcode + switch { + case c.isPtr: + code = newOpCode(ctx, c.typ, OpIntPtr) + case c.isString: + code = newOpCode(ctx, c.typ, OpIntString) + default: + code = newOpCode(ctx, c.typ, OpInt) + } + code.NumBitSize = c.bitSize + ctx.incIndex() + return Opcodes{code} +} + +func (c *IntCode) Filter(_ *FieldQuery) Code { + return c +} + +type UintCode struct { + typ *runtime.Type + bitSize uint8 + isString bool + isPtr bool +} + +func (c *UintCode) Kind() CodeKind { + return CodeKindUint +} + +func (c *UintCode) ToOpcode(ctx *compileContext) Opcodes { + var code *Opcode + switch { + case c.isPtr: + code = newOpCode(ctx, c.typ, OpUintPtr) + case c.isString: + code = newOpCode(ctx, c.typ, OpUintString) + default: + code = newOpCode(ctx, c.typ, OpUint) + } + code.NumBitSize = c.bitSize + ctx.incIndex() + return Opcodes{code} +} + +func (c *UintCode) Filter(_ *FieldQuery) Code { + return c +} + +type FloatCode struct { + typ *runtime.Type + bitSize uint8 + isPtr bool +} + +func (c *FloatCode) Kind() CodeKind { + return CodeKindFloat +} + +func (c *FloatCode) ToOpcode(ctx *compileContext) Opcodes { + var code *Opcode + switch { + case c.isPtr: + switch c.bitSize { + case 32: + code = newOpCode(ctx, c.typ, OpFloat32Ptr) + default: + code = newOpCode(ctx, c.typ, OpFloat64Ptr) + } + default: + switch c.bitSize { + case 32: + code = newOpCode(ctx, c.typ, OpFloat32) + default: + code = newOpCode(ctx, c.typ, OpFloat64) + } + } + ctx.incIndex() + return Opcodes{code} +} + +func (c *FloatCode) Filter(_ *FieldQuery) Code { + return c +} + +type StringCode struct { + typ *runtime.Type + isPtr bool +} + +func (c *StringCode) Kind() CodeKind { + return CodeKindString +} + +func (c *StringCode) ToOpcode(ctx *compileContext) Opcodes { + isJSONNumberType := c.typ == runtime.Type2RType(jsonNumberType) + var code *Opcode + if c.isPtr { + if isJSONNumberType { + code = newOpCode(ctx, c.typ, OpNumberPtr) + } else { + code = newOpCode(ctx, c.typ, OpStringPtr) + } + } else { + if isJSONNumberType { + code = newOpCode(ctx, c.typ, OpNumber) + } else { + code = newOpCode(ctx, c.typ, OpString) + } + } + ctx.incIndex() + return Opcodes{code} +} + +func (c *StringCode) Filter(_ *FieldQuery) Code { + return c +} + +type BoolCode struct { + typ *runtime.Type + isPtr bool +} + +func (c *BoolCode) Kind() CodeKind { + return CodeKindBool +} + +func (c *BoolCode) ToOpcode(ctx *compileContext) Opcodes { + var code *Opcode + switch { + case c.isPtr: + code = newOpCode(ctx, c.typ, OpBoolPtr) + default: + code = newOpCode(ctx, c.typ, OpBool) + } + ctx.incIndex() + return Opcodes{code} +} + +func (c *BoolCode) Filter(_ *FieldQuery) Code { + return c +} + +type BytesCode struct { + typ *runtime.Type + isPtr bool +} + +func (c *BytesCode) Kind() CodeKind { + return CodeKindBytes +} + +func (c *BytesCode) ToOpcode(ctx *compileContext) Opcodes { + var code *Opcode + switch { + case c.isPtr: + code = newOpCode(ctx, c.typ, OpBytesPtr) + default: + code = newOpCode(ctx, c.typ, OpBytes) + } + ctx.incIndex() + return Opcodes{code} +} + +func (c *BytesCode) Filter(_ *FieldQuery) Code { + return c +} + +type SliceCode struct { + typ *runtime.Type + value Code +} + +func (c *SliceCode) Kind() CodeKind { + return CodeKindSlice +} + +func (c *SliceCode) ToOpcode(ctx *compileContext) Opcodes { + // header => opcode => elem => end + // ^ | + // |________| + size := c.typ.Elem().Size() + header := newSliceHeaderCode(ctx, c.typ) + ctx.incIndex() + + ctx.incIndent() + codes := c.value.ToOpcode(ctx) + ctx.decIndent() + + codes.First().Flags |= IndirectFlags + elemCode := newSliceElemCode(ctx, c.typ.Elem(), header, size) + ctx.incIndex() + end := newOpCode(ctx, c.typ, OpSliceEnd) + ctx.incIndex() + header.End = end + header.Next = codes.First() + codes.Last().Next = elemCode + elemCode.Next = codes.First() + elemCode.End = end + return Opcodes{header}.Add(codes...).Add(elemCode).Add(end) +} + +func (c *SliceCode) Filter(_ *FieldQuery) Code { + return c +} + +type ArrayCode struct { + typ *runtime.Type + value Code +} + +func (c *ArrayCode) Kind() CodeKind { + return CodeKindArray +} + +func (c *ArrayCode) ToOpcode(ctx *compileContext) Opcodes { + // header => opcode => elem => end + // ^ | + // |________| + elem := c.typ.Elem() + alen := c.typ.Len() + size := elem.Size() + + header := newArrayHeaderCode(ctx, c.typ, alen) + ctx.incIndex() + + ctx.incIndent() + codes := c.value.ToOpcode(ctx) + ctx.decIndent() + + codes.First().Flags |= IndirectFlags + + elemCode := newArrayElemCode(ctx, elem, header, alen, size) + ctx.incIndex() + + end := newOpCode(ctx, c.typ, OpArrayEnd) + ctx.incIndex() + + header.End = end + header.Next = codes.First() + codes.Last().Next = elemCode + elemCode.Next = codes.First() + elemCode.End = end + + return Opcodes{header}.Add(codes...).Add(elemCode).Add(end) +} + +func (c *ArrayCode) Filter(_ *FieldQuery) Code { + return c +} + +type MapCode struct { + typ *runtime.Type + key Code + value Code +} + +func (c *MapCode) Kind() CodeKind { + return CodeKindMap +} + +func (c *MapCode) ToOpcode(ctx *compileContext) Opcodes { + // header => code => value => code => key => code => value => code => end + // ^ | + // |_______________________| + header := newMapHeaderCode(ctx, c.typ) + ctx.incIndex() + + keyCodes := c.key.ToOpcode(ctx) + + value := newMapValueCode(ctx, c.typ.Elem(), header) + ctx.incIndex() + + ctx.incIndent() + valueCodes := c.value.ToOpcode(ctx) + ctx.decIndent() + + valueCodes.First().Flags |= IndirectFlags + + key := newMapKeyCode(ctx, c.typ.Key(), header) + ctx.incIndex() + + end := newMapEndCode(ctx, c.typ, header) + ctx.incIndex() + + header.Next = keyCodes.First() + keyCodes.Last().Next = value + value.Next = valueCodes.First() + valueCodes.Last().Next = key + key.Next = keyCodes.First() + + header.End = end + key.End = end + value.End = end + return Opcodes{header}.Add(keyCodes...).Add(value).Add(valueCodes...).Add(key).Add(end) +} + +func (c *MapCode) Filter(_ *FieldQuery) Code { + return c +} + +type StructCode struct { + typ *runtime.Type + fields []*StructFieldCode + isPtr bool + disableIndirectConversion bool + isIndirect bool + isRecursive bool +} + +func (c *StructCode) Kind() CodeKind { + return CodeKindStruct +} + +func (c *StructCode) lastFieldCode(field *StructFieldCode, firstField *Opcode) *Opcode { + if isEmbeddedStruct(field) { + return c.lastAnonymousFieldCode(firstField) + } + lastField := firstField + for lastField.NextField != nil { + lastField = lastField.NextField + } + return lastField +} + +func (c *StructCode) lastAnonymousFieldCode(firstField *Opcode) *Opcode { + // firstField is special StructHead operation for anonymous structure. + // So, StructHead's next operation is truly struct head operation. + for firstField.Op == OpStructHead || firstField.Op == OpStructField { + firstField = firstField.Next + } + lastField := firstField + for lastField.NextField != nil { + lastField = lastField.NextField + } + return lastField +} + +func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes { + // header => code => structField => code => end + // ^ | + // |__________| + if c.isRecursive { + recursive := newRecursiveCode(ctx, c.typ, &CompiledCode{}) + recursive.Type = c.typ + ctx.incIndex() + *ctx.recursiveCodes = append(*ctx.recursiveCodes, recursive) + return Opcodes{recursive} + } + codes := Opcodes{} + var prevField *Opcode + ctx.incIndent() + for idx, field := range c.fields { + isFirstField := idx == 0 + isEndField := idx == len(c.fields)-1 + fieldCodes := field.ToOpcode(ctx, isFirstField, isEndField) + for _, code := range fieldCodes { + if c.isIndirect { + code.Flags |= IndirectFlags + } + } + firstField := fieldCodes.First() + if len(codes) > 0 { + codes.Last().Next = firstField + firstField.Idx = codes.First().Idx + } + if prevField != nil { + prevField.NextField = firstField + } + if isEndField { + endField := fieldCodes.Last() + if len(codes) > 0 { + codes.First().End = endField + } else { + firstField.End = endField + } + codes = codes.Add(fieldCodes...) + break + } + prevField = c.lastFieldCode(field, firstField) + codes = codes.Add(fieldCodes...) + } + if len(codes) == 0 { + head := &Opcode{ + Op: OpStructHead, + Idx: opcodeOffset(ctx.ptrIndex), + Type: c.typ, + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + } + ctx.incOpcodeIndex() + end := &Opcode{ + Op: OpStructEnd, + Idx: opcodeOffset(ctx.ptrIndex), + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + } + head.NextField = end + head.Next = end + head.End = end + codes = codes.Add(head, end) + ctx.incIndex() + } + ctx.decIndent() + ctx.structTypeToCodes[uintptr(unsafe.Pointer(c.typ))] = codes + return codes +} + +func (c *StructCode) ToAnonymousOpcode(ctx *compileContext) Opcodes { + // header => code => structField => code => end + // ^ | + // |__________| + if c.isRecursive { + recursive := newRecursiveCode(ctx, c.typ, &CompiledCode{}) + recursive.Type = c.typ + ctx.incIndex() + *ctx.recursiveCodes = append(*ctx.recursiveCodes, recursive) + return Opcodes{recursive} + } + codes := Opcodes{} + var prevField *Opcode + for idx, field := range c.fields { + isFirstField := idx == 0 + isEndField := idx == len(c.fields)-1 + fieldCodes := field.ToAnonymousOpcode(ctx, isFirstField, isEndField) + for _, code := range fieldCodes { + if c.isIndirect { + code.Flags |= IndirectFlags + } + } + firstField := fieldCodes.First() + if len(codes) > 0 { + codes.Last().Next = firstField + firstField.Idx = codes.First().Idx + } + if prevField != nil { + prevField.NextField = firstField + } + if isEndField { + lastField := fieldCodes.Last() + if len(codes) > 0 { + codes.First().End = lastField + } else { + firstField.End = lastField + } + } + prevField = firstField + codes = codes.Add(fieldCodes...) + } + return codes +} + +func (c *StructCode) removeFieldsByTags(tags runtime.StructTags) { + fields := make([]*StructFieldCode, 0, len(c.fields)) + for _, field := range c.fields { + if field.isAnonymous { + structCode := field.getAnonymousStruct() + if structCode != nil && !structCode.isRecursive { + structCode.removeFieldsByTags(tags) + if len(structCode.fields) > 0 { + fields = append(fields, field) + } + continue + } + } + if tags.ExistsKey(field.key) { + continue + } + fields = append(fields, field) + } + c.fields = fields +} + +func (c *StructCode) enableIndirect() { + if c.isIndirect { + return + } + c.isIndirect = true + if len(c.fields) == 0 { + return + } + structCode := c.fields[0].getStruct() + if structCode == nil { + return + } + structCode.enableIndirect() +} + +func (c *StructCode) Filter(query *FieldQuery) Code { + fieldMap := map[string]*FieldQuery{} + for _, field := range query.Fields { + fieldMap[field.Name] = field + } + fields := make([]*StructFieldCode, 0, len(c.fields)) + for _, field := range c.fields { + query, exists := fieldMap[field.key] + if !exists { + continue + } + fieldCode := &StructFieldCode{ + typ: field.typ, + key: field.key, + tag: field.tag, + value: field.value, + offset: field.offset, + isAnonymous: field.isAnonymous, + isTaggedKey: field.isTaggedKey, + isNilableType: field.isNilableType, + isNilCheck: field.isNilCheck, + isAddrForMarshaler: field.isAddrForMarshaler, + isNextOpPtrType: field.isNextOpPtrType, + } + if len(query.Fields) > 0 { + fieldCode.value = fieldCode.value.Filter(query) + } + fields = append(fields, fieldCode) + } + return &StructCode{ + typ: c.typ, + fields: fields, + isPtr: c.isPtr, + disableIndirectConversion: c.disableIndirectConversion, + isIndirect: c.isIndirect, + isRecursive: c.isRecursive, + } +} + +type StructFieldCode struct { + typ *runtime.Type + key string + tag *runtime.StructTag + value Code + offset uintptr + isAnonymous bool + isTaggedKey bool + isNilableType bool + isNilCheck bool + isAddrForMarshaler bool + isNextOpPtrType bool + isMarshalerContext bool +} + +func (c *StructFieldCode) getStruct() *StructCode { + value := c.value + ptr, ok := value.(*PtrCode) + if ok { + value = ptr.value + } + structCode, ok := value.(*StructCode) + if ok { + return structCode + } + return nil +} + +func (c *StructFieldCode) getAnonymousStruct() *StructCode { + if !c.isAnonymous { + return nil + } + return c.getStruct() +} + +func optimizeStructHeader(code *Opcode, tag *runtime.StructTag) OpType { + headType := code.ToHeaderType(tag.IsString) + if tag.IsOmitEmpty { + headType = headType.HeadToOmitEmptyHead() + } + return headType +} + +func optimizeStructField(code *Opcode, tag *runtime.StructTag) OpType { + fieldType := code.ToFieldType(tag.IsString) + if tag.IsOmitEmpty { + fieldType = fieldType.FieldToOmitEmptyField() + } + return fieldType +} + +func (c *StructFieldCode) headerOpcodes(ctx *compileContext, field *Opcode, valueCodes Opcodes) Opcodes { + value := valueCodes.First() + op := optimizeStructHeader(value, c.tag) + field.Op = op + if value.Flags&MarshalerContextFlags != 0 { + field.Flags |= MarshalerContextFlags + } + field.NumBitSize = value.NumBitSize + field.PtrNum = value.PtrNum + field.FieldQuery = value.FieldQuery + fieldCodes := Opcodes{field} + if op.IsMultipleOpHead() { + field.Next = value + fieldCodes = fieldCodes.Add(valueCodes...) + } else { + ctx.decIndex() + } + return fieldCodes +} + +func (c *StructFieldCode) fieldOpcodes(ctx *compileContext, field *Opcode, valueCodes Opcodes) Opcodes { + value := valueCodes.First() + op := optimizeStructField(value, c.tag) + field.Op = op + if value.Flags&MarshalerContextFlags != 0 { + field.Flags |= MarshalerContextFlags + } + field.NumBitSize = value.NumBitSize + field.PtrNum = value.PtrNum + field.FieldQuery = value.FieldQuery + + fieldCodes := Opcodes{field} + if op.IsMultipleOpField() { + field.Next = value + fieldCodes = fieldCodes.Add(valueCodes...) + } else { + ctx.decIndex() + } + return fieldCodes +} + +func (c *StructFieldCode) addStructEndCode(ctx *compileContext, codes Opcodes) Opcodes { + end := &Opcode{ + Op: OpStructEnd, + Idx: opcodeOffset(ctx.ptrIndex), + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + } + codes.Last().Next = end + code := codes.First() + for code.Op == OpStructField || code.Op == OpStructHead { + code = code.Next + } + for code.NextField != nil { + code = code.NextField + } + code.NextField = end + + codes = codes.Add(end) + ctx.incOpcodeIndex() + return codes +} + +func (c *StructFieldCode) structKey(ctx *compileContext) string { + if ctx.escapeKey { + rctx := &RuntimeContext{Option: &Option{Flag: HTMLEscapeOption}} + return fmt.Sprintf(`%s:`, string(AppendString(rctx, []byte{}, c.key))) + } + return fmt.Sprintf(`"%s":`, c.key) +} + +func (c *StructFieldCode) flags() OpFlags { + var flags OpFlags + if c.isTaggedKey { + flags |= IsTaggedKeyFlags + } + if c.isNilableType { + flags |= IsNilableTypeFlags + } + if c.isNilCheck { + flags |= NilCheckFlags + } + if c.isAddrForMarshaler { + flags |= AddrForMarshalerFlags + } + if c.isNextOpPtrType { + flags |= IsNextOpPtrTypeFlags + } + if c.isAnonymous { + flags |= AnonymousKeyFlags + } + if c.isMarshalerContext { + flags |= MarshalerContextFlags + } + return flags +} + +func (c *StructFieldCode) toValueOpcodes(ctx *compileContext) Opcodes { + if c.isAnonymous { + anonymCode, ok := c.value.(AnonymousCode) + if ok { + return anonymCode.ToAnonymousOpcode(ctx) + } + } + return c.value.ToOpcode(ctx) +} + +func (c *StructFieldCode) ToOpcode(ctx *compileContext, isFirstField, isEndField bool) Opcodes { + field := &Opcode{ + Idx: opcodeOffset(ctx.ptrIndex), + Flags: c.flags(), + Key: c.structKey(ctx), + Offset: uint32(c.offset), + Type: c.typ, + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + DisplayKey: c.key, + } + ctx.incIndex() + valueCodes := c.toValueOpcodes(ctx) + if isFirstField { + codes := c.headerOpcodes(ctx, field, valueCodes) + if isEndField { + codes = c.addStructEndCode(ctx, codes) + } + return codes + } + codes := c.fieldOpcodes(ctx, field, valueCodes) + if isEndField { + if isEnableStructEndOptimization(c.value) { + field.Op = field.Op.FieldToEnd() + } else { + codes = c.addStructEndCode(ctx, codes) + } + } + return codes +} + +func (c *StructFieldCode) ToAnonymousOpcode(ctx *compileContext, isFirstField, isEndField bool) Opcodes { + field := &Opcode{ + Idx: opcodeOffset(ctx.ptrIndex), + Flags: c.flags() | AnonymousHeadFlags, + Key: c.structKey(ctx), + Offset: uint32(c.offset), + Type: c.typ, + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + DisplayKey: c.key, + } + ctx.incIndex() + valueCodes := c.toValueOpcodes(ctx) + if isFirstField { + return c.headerOpcodes(ctx, field, valueCodes) + } + return c.fieldOpcodes(ctx, field, valueCodes) +} + +func isEnableStructEndOptimization(value Code) bool { + switch value.Kind() { + case CodeKindInt, + CodeKindUint, + CodeKindFloat, + CodeKindString, + CodeKindBool, + CodeKindBytes: + return true + case CodeKindPtr: + return isEnableStructEndOptimization(value.(*PtrCode).value) + default: + return false + } +} + +type InterfaceCode struct { + typ *runtime.Type + fieldQuery *FieldQuery + isPtr bool +} + +func (c *InterfaceCode) Kind() CodeKind { + return CodeKindInterface +} + +func (c *InterfaceCode) ToOpcode(ctx *compileContext) Opcodes { + var code *Opcode + switch { + case c.isPtr: + code = newOpCode(ctx, c.typ, OpInterfacePtr) + default: + code = newOpCode(ctx, c.typ, OpInterface) + } + code.FieldQuery = c.fieldQuery + if c.typ.NumMethod() > 0 { + code.Flags |= NonEmptyInterfaceFlags + } + ctx.incIndex() + return Opcodes{code} +} + +func (c *InterfaceCode) Filter(query *FieldQuery) Code { + return &InterfaceCode{ + typ: c.typ, + fieldQuery: query, + isPtr: c.isPtr, + } +} + +type MarshalJSONCode struct { + typ *runtime.Type + fieldQuery *FieldQuery + isAddrForMarshaler bool + isNilableType bool + isMarshalerContext bool +} + +func (c *MarshalJSONCode) Kind() CodeKind { + return CodeKindMarshalJSON +} + +func (c *MarshalJSONCode) ToOpcode(ctx *compileContext) Opcodes { + code := newOpCode(ctx, c.typ, OpMarshalJSON) + code.FieldQuery = c.fieldQuery + if c.isAddrForMarshaler { + code.Flags |= AddrForMarshalerFlags + } + if c.isMarshalerContext { + code.Flags |= MarshalerContextFlags + } + if c.isNilableType { + code.Flags |= IsNilableTypeFlags + } else { + code.Flags &= ^IsNilableTypeFlags + } + ctx.incIndex() + return Opcodes{code} +} + +func (c *MarshalJSONCode) Filter(query *FieldQuery) Code { + return &MarshalJSONCode{ + typ: c.typ, + fieldQuery: query, + isAddrForMarshaler: c.isAddrForMarshaler, + isNilableType: c.isNilableType, + isMarshalerContext: c.isMarshalerContext, + } +} + +type MarshalTextCode struct { + typ *runtime.Type + fieldQuery *FieldQuery + isAddrForMarshaler bool + isNilableType bool +} + +func (c *MarshalTextCode) Kind() CodeKind { + return CodeKindMarshalText +} + +func (c *MarshalTextCode) ToOpcode(ctx *compileContext) Opcodes { + code := newOpCode(ctx, c.typ, OpMarshalText) + code.FieldQuery = c.fieldQuery + if c.isAddrForMarshaler { + code.Flags |= AddrForMarshalerFlags + } + if c.isNilableType { + code.Flags |= IsNilableTypeFlags + } else { + code.Flags &= ^IsNilableTypeFlags + } + ctx.incIndex() + return Opcodes{code} +} + +func (c *MarshalTextCode) Filter(query *FieldQuery) Code { + return &MarshalTextCode{ + typ: c.typ, + fieldQuery: query, + isAddrForMarshaler: c.isAddrForMarshaler, + isNilableType: c.isNilableType, + } +} + +type PtrCode struct { + typ *runtime.Type + value Code + ptrNum uint8 +} + +func (c *PtrCode) Kind() CodeKind { + return CodeKindPtr +} + +func (c *PtrCode) ToOpcode(ctx *compileContext) Opcodes { + codes := c.value.ToOpcode(ctx) + codes.First().Op = convertPtrOp(codes.First()) + codes.First().PtrNum = c.ptrNum + return codes +} + +func (c *PtrCode) ToAnonymousOpcode(ctx *compileContext) Opcodes { + var codes Opcodes + anonymCode, ok := c.value.(AnonymousCode) + if ok { + codes = anonymCode.ToAnonymousOpcode(ctx) + } else { + codes = c.value.ToOpcode(ctx) + } + codes.First().Op = convertPtrOp(codes.First()) + codes.First().PtrNum = c.ptrNum + return codes +} + +func (c *PtrCode) Filter(query *FieldQuery) Code { + return &PtrCode{ + typ: c.typ, + value: c.value.Filter(query), + ptrNum: c.ptrNum, + } +} + +func convertPtrOp(code *Opcode) OpType { + ptrHeadOp := code.Op.HeadToPtrHead() + if code.Op != ptrHeadOp { + if code.PtrNum > 0 { + // ptr field and ptr head + code.PtrNum-- + } + return ptrHeadOp + } + switch code.Op { + case OpInt: + return OpIntPtr + case OpUint: + return OpUintPtr + case OpFloat32: + return OpFloat32Ptr + case OpFloat64: + return OpFloat64Ptr + case OpString: + return OpStringPtr + case OpBool: + return OpBoolPtr + case OpBytes: + return OpBytesPtr + case OpNumber: + return OpNumberPtr + case OpArray: + return OpArrayPtr + case OpSlice: + return OpSlicePtr + case OpMap: + return OpMapPtr + case OpMarshalJSON: + return OpMarshalJSONPtr + case OpMarshalText: + return OpMarshalTextPtr + case OpInterface: + return OpInterfacePtr + case OpRecursive: + return OpRecursivePtr + } + return code.Op +} + +func isEmbeddedStruct(field *StructFieldCode) bool { + if !field.isAnonymous { + return false + } + t := field.typ + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + return t.Kind() == reflect.Struct +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compact.go b/vendor/github.com/goccy/go-json/internal/encoder/compact.go new file mode 100644 index 000000000..0eb9545d8 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/compact.go @@ -0,0 +1,286 @@ +package encoder + +import ( + "bytes" + "fmt" + "strconv" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +var ( + isWhiteSpace = [256]bool{ + ' ': true, + '\n': true, + '\t': true, + '\r': true, + } + isHTMLEscapeChar = [256]bool{ + '<': true, + '>': true, + '&': true, + } + nul = byte('\000') +) + +func Compact(buf *bytes.Buffer, src []byte, escape bool) error { + if len(src) == 0 { + return errors.ErrUnexpectedEndOfJSON("", 0) + } + buf.Grow(len(src)) + dst := buf.Bytes() + + ctx := TakeRuntimeContext() + ctxBuf := ctx.Buf[:0] + ctxBuf = append(append(ctxBuf, src...), nul) + ctx.Buf = ctxBuf + + if err := compactAndWrite(buf, dst, ctxBuf, escape); err != nil { + ReleaseRuntimeContext(ctx) + return err + } + ReleaseRuntimeContext(ctx) + return nil +} + +func compactAndWrite(buf *bytes.Buffer, dst []byte, src []byte, escape bool) error { + dst, err := compact(dst, src, escape) + if err != nil { + return err + } + if _, err := buf.Write(dst); err != nil { + return err + } + return nil +} + +func compact(dst, src []byte, escape bool) ([]byte, error) { + buf, cursor, err := compactValue(dst, src, 0, escape) + if err != nil { + return nil, err + } + if err := validateEndBuf(src, cursor); err != nil { + return nil, err + } + return buf, nil +} + +func validateEndBuf(src []byte, cursor int64) error { + for { + switch src[cursor] { + case ' ', '\t', '\n', '\r': + cursor++ + continue + case nul: + return nil + } + return errors.ErrSyntax( + fmt.Sprintf("invalid character '%c' after top-level value", src[cursor]), + cursor+1, + ) + } +} + +func skipWhiteSpace(buf []byte, cursor int64) int64 { +LOOP: + if isWhiteSpace[buf[cursor]] { + cursor++ + goto LOOP + } + return cursor +} + +func compactValue(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) { + for { + switch src[cursor] { + case ' ', '\t', '\n', '\r': + cursor++ + continue + case '{': + return compactObject(dst, src, cursor, escape) + case '}': + return nil, 0, errors.ErrSyntax("unexpected character '}'", cursor) + case '[': + return compactArray(dst, src, cursor, escape) + case ']': + return nil, 0, errors.ErrSyntax("unexpected character ']'", cursor) + case '"': + return compactString(dst, src, cursor, escape) + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return compactNumber(dst, src, cursor) + case 't': + return compactTrue(dst, src, cursor) + case 'f': + return compactFalse(dst, src, cursor) + case 'n': + return compactNull(dst, src, cursor) + default: + return nil, 0, errors.ErrSyntax(fmt.Sprintf("unexpected character '%c'", src[cursor]), cursor) + } + } +} + +func compactObject(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) { + if src[cursor] == '{' { + dst = append(dst, '{') + } else { + return nil, 0, errors.ErrExpected("expected { character for object value", cursor) + } + cursor = skipWhiteSpace(src, cursor+1) + if src[cursor] == '}' { + dst = append(dst, '}') + return dst, cursor + 1, nil + } + var err error + for { + cursor = skipWhiteSpace(src, cursor) + dst, cursor, err = compactString(dst, src, cursor, escape) + if err != nil { + return nil, 0, err + } + cursor = skipWhiteSpace(src, cursor) + if src[cursor] != ':' { + return nil, 0, errors.ErrExpected("colon after object key", cursor) + } + dst = append(dst, ':') + dst, cursor, err = compactValue(dst, src, cursor+1, escape) + if err != nil { + return nil, 0, err + } + cursor = skipWhiteSpace(src, cursor) + switch src[cursor] { + case '}': + dst = append(dst, '}') + cursor++ + return dst, cursor, nil + case ',': + dst = append(dst, ',') + default: + return nil, 0, errors.ErrExpected("comma after object value", cursor) + } + cursor++ + } +} + +func compactArray(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) { + if src[cursor] == '[' { + dst = append(dst, '[') + } else { + return nil, 0, errors.ErrExpected("expected [ character for array value", cursor) + } + cursor = skipWhiteSpace(src, cursor+1) + if src[cursor] == ']' { + dst = append(dst, ']') + return dst, cursor + 1, nil + } + var err error + for { + dst, cursor, err = compactValue(dst, src, cursor, escape) + if err != nil { + return nil, 0, err + } + cursor = skipWhiteSpace(src, cursor) + switch src[cursor] { + case ']': + dst = append(dst, ']') + cursor++ + return dst, cursor, nil + case ',': + dst = append(dst, ',') + default: + return nil, 0, errors.ErrExpected("comma after array value", cursor) + } + cursor++ + } +} + +func compactString(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) { + if src[cursor] != '"' { + return nil, 0, errors.ErrInvalidCharacter(src[cursor], "string", cursor) + } + start := cursor + for { + cursor++ + c := src[cursor] + if escape { + if isHTMLEscapeChar[c] { + dst = append(dst, src[start:cursor]...) + dst = append(dst, `\u00`...) + dst = append(dst, hex[c>>4], hex[c&0xF]) + start = cursor + 1 + } else if c == 0xE2 && cursor+2 < int64(len(src)) && src[cursor+1] == 0x80 && src[cursor+2]&^1 == 0xA8 { + dst = append(dst, src[start:cursor]...) + dst = append(dst, `\u202`...) + dst = append(dst, hex[src[cursor+2]&0xF]) + cursor += 2 + start = cursor + 3 + } + } + switch c { + case '\\': + cursor++ + if src[cursor] == nul { + return nil, 0, errors.ErrUnexpectedEndOfJSON("string", int64(len(src))) + } + case '"': + cursor++ + return append(dst, src[start:cursor]...), cursor, nil + case nul: + return nil, 0, errors.ErrUnexpectedEndOfJSON("string", int64(len(src))) + } + } +} + +func compactNumber(dst, src []byte, cursor int64) ([]byte, int64, error) { + start := cursor + for { + cursor++ + if floatTable[src[cursor]] { + continue + } + break + } + num := src[start:cursor] + if _, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&num)), 64); err != nil { + return nil, 0, err + } + dst = append(dst, num...) + return dst, cursor, nil +} + +func compactTrue(dst, src []byte, cursor int64) ([]byte, int64, error) { + if cursor+3 >= int64(len(src)) { + return nil, 0, errors.ErrUnexpectedEndOfJSON("true", cursor) + } + if !bytes.Equal(src[cursor:cursor+4], []byte(`true`)) { + return nil, 0, errors.ErrInvalidCharacter(src[cursor], "true", cursor) + } + dst = append(dst, "true"...) + cursor += 4 + return dst, cursor, nil +} + +func compactFalse(dst, src []byte, cursor int64) ([]byte, int64, error) { + if cursor+4 >= int64(len(src)) { + return nil, 0, errors.ErrUnexpectedEndOfJSON("false", cursor) + } + if !bytes.Equal(src[cursor:cursor+5], []byte(`false`)) { + return nil, 0, errors.ErrInvalidCharacter(src[cursor], "false", cursor) + } + dst = append(dst, "false"...) + cursor += 5 + return dst, cursor, nil +} + +func compactNull(dst, src []byte, cursor int64) ([]byte, int64, error) { + if cursor+3 >= int64(len(src)) { + return nil, 0, errors.ErrUnexpectedEndOfJSON("null", cursor) + } + if !bytes.Equal(src[cursor:cursor+4], []byte(`null`)) { + return nil, 0, errors.ErrInvalidCharacter(src[cursor], "null", cursor) + } + dst = append(dst, "null"...) + cursor += 4 + return dst, cursor, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compiler.go b/vendor/github.com/goccy/go-json/internal/encoder/compiler.go new file mode 100644 index 000000000..3ae39ba8c --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/compiler.go @@ -0,0 +1,935 @@ +package encoder + +import ( + "context" + "encoding" + "encoding/json" + "reflect" + "sync/atomic" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type marshalerContext interface { + MarshalJSON(context.Context) ([]byte, error) +} + +var ( + marshalJSONType = reflect.TypeOf((*json.Marshaler)(nil)).Elem() + marshalJSONContextType = reflect.TypeOf((*marshalerContext)(nil)).Elem() + marshalTextType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() + jsonNumberType = reflect.TypeOf(json.Number("")) + cachedOpcodeSets []*OpcodeSet + cachedOpcodeMap unsafe.Pointer // map[uintptr]*OpcodeSet + typeAddr *runtime.TypeAddr +) + +func init() { + typeAddr = runtime.AnalyzeTypeAddr() + if typeAddr == nil { + typeAddr = &runtime.TypeAddr{} + } + cachedOpcodeSets = make([]*OpcodeSet, typeAddr.AddrRange>>typeAddr.AddrShift+1) +} + +func loadOpcodeMap() map[uintptr]*OpcodeSet { + p := atomic.LoadPointer(&cachedOpcodeMap) + return *(*map[uintptr]*OpcodeSet)(unsafe.Pointer(&p)) +} + +func storeOpcodeSet(typ uintptr, set *OpcodeSet, m map[uintptr]*OpcodeSet) { + newOpcodeMap := make(map[uintptr]*OpcodeSet, len(m)+1) + newOpcodeMap[typ] = set + + for k, v := range m { + newOpcodeMap[k] = v + } + + atomic.StorePointer(&cachedOpcodeMap, *(*unsafe.Pointer)(unsafe.Pointer(&newOpcodeMap))) +} + +func compileToGetCodeSetSlowPath(typeptr uintptr) (*OpcodeSet, error) { + opcodeMap := loadOpcodeMap() + if codeSet, exists := opcodeMap[typeptr]; exists { + return codeSet, nil + } + codeSet, err := newCompiler().compile(typeptr) + if err != nil { + return nil, err + } + storeOpcodeSet(typeptr, codeSet, opcodeMap) + return codeSet, nil +} + +func getFilteredCodeSetIfNeeded(ctx *RuntimeContext, codeSet *OpcodeSet) (*OpcodeSet, error) { + if (ctx.Option.Flag & ContextOption) == 0 { + return codeSet, nil + } + query := FieldQueryFromContext(ctx.Option.Context) + if query == nil { + return codeSet, nil + } + ctx.Option.Flag |= FieldQueryOption + cacheCodeSet := codeSet.getQueryCache(query.Hash()) + if cacheCodeSet != nil { + return cacheCodeSet, nil + } + queryCodeSet, err := newCompiler().codeToOpcodeSet(codeSet.Type, codeSet.Code.Filter(query)) + if err != nil { + return nil, err + } + codeSet.setQueryCache(query.Hash(), queryCodeSet) + return queryCodeSet, nil +} + +type Compiler struct { + structTypeToCode map[uintptr]*StructCode +} + +func newCompiler() *Compiler { + return &Compiler{ + structTypeToCode: map[uintptr]*StructCode{}, + } +} + +func (c *Compiler) compile(typeptr uintptr) (*OpcodeSet, error) { + // noescape trick for header.typ ( reflect.*rtype ) + typ := *(**runtime.Type)(unsafe.Pointer(&typeptr)) + code, err := c.typeToCode(typ) + if err != nil { + return nil, err + } + return c.codeToOpcodeSet(typ, code) +} + +func (c *Compiler) codeToOpcodeSet(typ *runtime.Type, code Code) (*OpcodeSet, error) { + noescapeKeyCode := c.codeToOpcode(&compileContext{ + structTypeToCodes: map[uintptr]Opcodes{}, + recursiveCodes: &Opcodes{}, + }, typ, code) + if err := noescapeKeyCode.Validate(); err != nil { + return nil, err + } + escapeKeyCode := c.codeToOpcode(&compileContext{ + structTypeToCodes: map[uintptr]Opcodes{}, + recursiveCodes: &Opcodes{}, + escapeKey: true, + }, typ, code) + noescapeKeyCode = copyOpcode(noescapeKeyCode) + escapeKeyCode = copyOpcode(escapeKeyCode) + setTotalLengthToInterfaceOp(noescapeKeyCode) + setTotalLengthToInterfaceOp(escapeKeyCode) + interfaceNoescapeKeyCode := copyToInterfaceOpcode(noescapeKeyCode) + interfaceEscapeKeyCode := copyToInterfaceOpcode(escapeKeyCode) + codeLength := noescapeKeyCode.TotalLength() + return &OpcodeSet{ + Type: typ, + NoescapeKeyCode: noescapeKeyCode, + EscapeKeyCode: escapeKeyCode, + InterfaceNoescapeKeyCode: interfaceNoescapeKeyCode, + InterfaceEscapeKeyCode: interfaceEscapeKeyCode, + CodeLength: codeLength, + EndCode: ToEndCode(interfaceNoescapeKeyCode), + Code: code, + QueryCache: map[string]*OpcodeSet{}, + }, nil +} + +func (c *Compiler) typeToCode(typ *runtime.Type) (Code, error) { + switch { + case c.implementsMarshalJSON(typ): + return c.marshalJSONCode(typ) + case c.implementsMarshalText(typ): + return c.marshalTextCode(typ) + } + + isPtr := false + orgType := typ + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + isPtr = true + } + switch { + case c.implementsMarshalJSON(typ): + return c.marshalJSONCode(orgType) + case c.implementsMarshalText(typ): + return c.marshalTextCode(orgType) + } + switch typ.Kind() { + case reflect.Slice: + elem := typ.Elem() + if elem.Kind() == reflect.Uint8 { + p := runtime.PtrTo(elem) + if !c.implementsMarshalJSONType(p) && !p.Implements(marshalTextType) { + return c.bytesCode(typ, isPtr) + } + } + return c.sliceCode(typ) + case reflect.Map: + if isPtr { + return c.ptrCode(runtime.PtrTo(typ)) + } + return c.mapCode(typ) + case reflect.Struct: + return c.structCode(typ, isPtr) + case reflect.Int: + return c.intCode(typ, isPtr) + case reflect.Int8: + return c.int8Code(typ, isPtr) + case reflect.Int16: + return c.int16Code(typ, isPtr) + case reflect.Int32: + return c.int32Code(typ, isPtr) + case reflect.Int64: + return c.int64Code(typ, isPtr) + case reflect.Uint, reflect.Uintptr: + return c.uintCode(typ, isPtr) + case reflect.Uint8: + return c.uint8Code(typ, isPtr) + case reflect.Uint16: + return c.uint16Code(typ, isPtr) + case reflect.Uint32: + return c.uint32Code(typ, isPtr) + case reflect.Uint64: + return c.uint64Code(typ, isPtr) + case reflect.Float32: + return c.float32Code(typ, isPtr) + case reflect.Float64: + return c.float64Code(typ, isPtr) + case reflect.String: + return c.stringCode(typ, isPtr) + case reflect.Bool: + return c.boolCode(typ, isPtr) + case reflect.Interface: + return c.interfaceCode(typ, isPtr) + default: + if isPtr && typ.Implements(marshalTextType) { + typ = orgType + } + return c.typeToCodeWithPtr(typ, isPtr) + } +} + +func (c *Compiler) typeToCodeWithPtr(typ *runtime.Type, isPtr bool) (Code, error) { + switch { + case c.implementsMarshalJSON(typ): + return c.marshalJSONCode(typ) + case c.implementsMarshalText(typ): + return c.marshalTextCode(typ) + } + switch typ.Kind() { + case reflect.Ptr: + return c.ptrCode(typ) + case reflect.Slice: + elem := typ.Elem() + if elem.Kind() == reflect.Uint8 { + p := runtime.PtrTo(elem) + if !c.implementsMarshalJSONType(p) && !p.Implements(marshalTextType) { + return c.bytesCode(typ, false) + } + } + return c.sliceCode(typ) + case reflect.Array: + return c.arrayCode(typ) + case reflect.Map: + return c.mapCode(typ) + case reflect.Struct: + return c.structCode(typ, isPtr) + case reflect.Interface: + return c.interfaceCode(typ, false) + case reflect.Int: + return c.intCode(typ, false) + case reflect.Int8: + return c.int8Code(typ, false) + case reflect.Int16: + return c.int16Code(typ, false) + case reflect.Int32: + return c.int32Code(typ, false) + case reflect.Int64: + return c.int64Code(typ, false) + case reflect.Uint: + return c.uintCode(typ, false) + case reflect.Uint8: + return c.uint8Code(typ, false) + case reflect.Uint16: + return c.uint16Code(typ, false) + case reflect.Uint32: + return c.uint32Code(typ, false) + case reflect.Uint64: + return c.uint64Code(typ, false) + case reflect.Uintptr: + return c.uintCode(typ, false) + case reflect.Float32: + return c.float32Code(typ, false) + case reflect.Float64: + return c.float64Code(typ, false) + case reflect.String: + return c.stringCode(typ, false) + case reflect.Bool: + return c.boolCode(typ, false) + } + return nil, &errors.UnsupportedTypeError{Type: runtime.RType2Type(typ)} +} + +const intSize = 32 << (^uint(0) >> 63) + +//nolint:unparam +func (c *Compiler) intCode(typ *runtime.Type, isPtr bool) (*IntCode, error) { + return &IntCode{typ: typ, bitSize: intSize, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) int8Code(typ *runtime.Type, isPtr bool) (*IntCode, error) { + return &IntCode{typ: typ, bitSize: 8, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) int16Code(typ *runtime.Type, isPtr bool) (*IntCode, error) { + return &IntCode{typ: typ, bitSize: 16, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) int32Code(typ *runtime.Type, isPtr bool) (*IntCode, error) { + return &IntCode{typ: typ, bitSize: 32, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) int64Code(typ *runtime.Type, isPtr bool) (*IntCode, error) { + return &IntCode{typ: typ, bitSize: 64, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) uintCode(typ *runtime.Type, isPtr bool) (*UintCode, error) { + return &UintCode{typ: typ, bitSize: intSize, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) uint8Code(typ *runtime.Type, isPtr bool) (*UintCode, error) { + return &UintCode{typ: typ, bitSize: 8, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) uint16Code(typ *runtime.Type, isPtr bool) (*UintCode, error) { + return &UintCode{typ: typ, bitSize: 16, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) uint32Code(typ *runtime.Type, isPtr bool) (*UintCode, error) { + return &UintCode{typ: typ, bitSize: 32, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) uint64Code(typ *runtime.Type, isPtr bool) (*UintCode, error) { + return &UintCode{typ: typ, bitSize: 64, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) float32Code(typ *runtime.Type, isPtr bool) (*FloatCode, error) { + return &FloatCode{typ: typ, bitSize: 32, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) float64Code(typ *runtime.Type, isPtr bool) (*FloatCode, error) { + return &FloatCode{typ: typ, bitSize: 64, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) stringCode(typ *runtime.Type, isPtr bool) (*StringCode, error) { + return &StringCode{typ: typ, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) boolCode(typ *runtime.Type, isPtr bool) (*BoolCode, error) { + return &BoolCode{typ: typ, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) intStringCode(typ *runtime.Type) (*IntCode, error) { + return &IntCode{typ: typ, bitSize: intSize, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) int8StringCode(typ *runtime.Type) (*IntCode, error) { + return &IntCode{typ: typ, bitSize: 8, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) int16StringCode(typ *runtime.Type) (*IntCode, error) { + return &IntCode{typ: typ, bitSize: 16, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) int32StringCode(typ *runtime.Type) (*IntCode, error) { + return &IntCode{typ: typ, bitSize: 32, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) int64StringCode(typ *runtime.Type) (*IntCode, error) { + return &IntCode{typ: typ, bitSize: 64, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) uintStringCode(typ *runtime.Type) (*UintCode, error) { + return &UintCode{typ: typ, bitSize: intSize, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) uint8StringCode(typ *runtime.Type) (*UintCode, error) { + return &UintCode{typ: typ, bitSize: 8, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) uint16StringCode(typ *runtime.Type) (*UintCode, error) { + return &UintCode{typ: typ, bitSize: 16, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) uint32StringCode(typ *runtime.Type) (*UintCode, error) { + return &UintCode{typ: typ, bitSize: 32, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) uint64StringCode(typ *runtime.Type) (*UintCode, error) { + return &UintCode{typ: typ, bitSize: 64, isString: true}, nil +} + +//nolint:unparam +func (c *Compiler) bytesCode(typ *runtime.Type, isPtr bool) (*BytesCode, error) { + return &BytesCode{typ: typ, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) interfaceCode(typ *runtime.Type, isPtr bool) (*InterfaceCode, error) { + return &InterfaceCode{typ: typ, isPtr: isPtr}, nil +} + +//nolint:unparam +func (c *Compiler) marshalJSONCode(typ *runtime.Type) (*MarshalJSONCode, error) { + return &MarshalJSONCode{ + typ: typ, + isAddrForMarshaler: c.isPtrMarshalJSONType(typ), + isNilableType: c.isNilableType(typ), + isMarshalerContext: typ.Implements(marshalJSONContextType) || runtime.PtrTo(typ).Implements(marshalJSONContextType), + }, nil +} + +//nolint:unparam +func (c *Compiler) marshalTextCode(typ *runtime.Type) (*MarshalTextCode, error) { + return &MarshalTextCode{ + typ: typ, + isAddrForMarshaler: c.isPtrMarshalTextType(typ), + isNilableType: c.isNilableType(typ), + }, nil +} + +func (c *Compiler) ptrCode(typ *runtime.Type) (*PtrCode, error) { + code, err := c.typeToCodeWithPtr(typ.Elem(), true) + if err != nil { + return nil, err + } + ptr, ok := code.(*PtrCode) + if ok { + return &PtrCode{typ: typ, value: ptr.value, ptrNum: ptr.ptrNum + 1}, nil + } + return &PtrCode{typ: typ, value: code, ptrNum: 1}, nil +} + +func (c *Compiler) sliceCode(typ *runtime.Type) (*SliceCode, error) { + elem := typ.Elem() + code, err := c.listElemCode(elem) + if err != nil { + return nil, err + } + if code.Kind() == CodeKindStruct { + structCode := code.(*StructCode) + structCode.enableIndirect() + } + return &SliceCode{typ: typ, value: code}, nil +} + +func (c *Compiler) arrayCode(typ *runtime.Type) (*ArrayCode, error) { + elem := typ.Elem() + code, err := c.listElemCode(elem) + if err != nil { + return nil, err + } + if code.Kind() == CodeKindStruct { + structCode := code.(*StructCode) + structCode.enableIndirect() + } + return &ArrayCode{typ: typ, value: code}, nil +} + +func (c *Compiler) mapCode(typ *runtime.Type) (*MapCode, error) { + keyCode, err := c.mapKeyCode(typ.Key()) + if err != nil { + return nil, err + } + valueCode, err := c.mapValueCode(typ.Elem()) + if err != nil { + return nil, err + } + if valueCode.Kind() == CodeKindStruct { + structCode := valueCode.(*StructCode) + structCode.enableIndirect() + } + return &MapCode{typ: typ, key: keyCode, value: valueCode}, nil +} + +func (c *Compiler) listElemCode(typ *runtime.Type) (Code, error) { + switch { + case c.isPtrMarshalJSONType(typ): + return c.marshalJSONCode(typ) + case !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType): + return c.marshalTextCode(typ) + case typ.Kind() == reflect.Map: + return c.ptrCode(runtime.PtrTo(typ)) + default: + // isPtr was originally used to indicate whether the type of top level is pointer. + // However, since the slice/array element is a specification that can get the pointer address, explicitly set isPtr to true. + // See here for related issues: https://github.com/goccy/go-json/issues/370 + code, err := c.typeToCodeWithPtr(typ, true) + if err != nil { + return nil, err + } + ptr, ok := code.(*PtrCode) + if ok { + if ptr.value.Kind() == CodeKindMap { + ptr.ptrNum++ + } + } + return code, nil + } +} + +func (c *Compiler) mapKeyCode(typ *runtime.Type) (Code, error) { + switch { + case c.implementsMarshalText(typ): + return c.marshalTextCode(typ) + } + switch typ.Kind() { + case reflect.Ptr: + return c.ptrCode(typ) + case reflect.String: + return c.stringCode(typ, false) + case reflect.Int: + return c.intStringCode(typ) + case reflect.Int8: + return c.int8StringCode(typ) + case reflect.Int16: + return c.int16StringCode(typ) + case reflect.Int32: + return c.int32StringCode(typ) + case reflect.Int64: + return c.int64StringCode(typ) + case reflect.Uint: + return c.uintStringCode(typ) + case reflect.Uint8: + return c.uint8StringCode(typ) + case reflect.Uint16: + return c.uint16StringCode(typ) + case reflect.Uint32: + return c.uint32StringCode(typ) + case reflect.Uint64: + return c.uint64StringCode(typ) + case reflect.Uintptr: + return c.uintStringCode(typ) + } + return nil, &errors.UnsupportedTypeError{Type: runtime.RType2Type(typ)} +} + +func (c *Compiler) mapValueCode(typ *runtime.Type) (Code, error) { + switch typ.Kind() { + case reflect.Map: + return c.ptrCode(runtime.PtrTo(typ)) + default: + code, err := c.typeToCodeWithPtr(typ, false) + if err != nil { + return nil, err + } + ptr, ok := code.(*PtrCode) + if ok { + if ptr.value.Kind() == CodeKindMap { + ptr.ptrNum++ + } + } + return code, nil + } +} + +func (c *Compiler) structCode(typ *runtime.Type, isPtr bool) (*StructCode, error) { + typeptr := uintptr(unsafe.Pointer(typ)) + if code, exists := c.structTypeToCode[typeptr]; exists { + derefCode := *code + derefCode.isRecursive = true + return &derefCode, nil + } + indirect := runtime.IfaceIndir(typ) + code := &StructCode{typ: typ, isPtr: isPtr, isIndirect: indirect} + c.structTypeToCode[typeptr] = code + + fieldNum := typ.NumField() + tags := c.typeToStructTags(typ) + fields := []*StructFieldCode{} + for i, tag := range tags { + isOnlyOneFirstField := i == 0 && fieldNum == 1 + field, err := c.structFieldCode(code, tag, isPtr, isOnlyOneFirstField) + if err != nil { + return nil, err + } + if field.isAnonymous { + structCode := field.getAnonymousStruct() + if structCode != nil { + structCode.removeFieldsByTags(tags) + if c.isAssignableIndirect(field, isPtr) { + if indirect { + structCode.isIndirect = true + } else { + structCode.isIndirect = false + } + } + } + } else { + structCode := field.getStruct() + if structCode != nil { + if indirect { + // if parent is indirect type, set child indirect property to true + structCode.isIndirect = true + } else { + // if parent is not indirect type, set child indirect property to false. + // but if parent's indirect is false and isPtr is true, then indirect must be true. + // Do this only if indirectConversion is enabled at the end of compileStruct. + structCode.isIndirect = false + } + } + } + fields = append(fields, field) + } + fieldMap := c.getFieldMap(fields) + duplicatedFieldMap := c.getDuplicatedFieldMap(fieldMap) + code.fields = c.filteredDuplicatedFields(fields, duplicatedFieldMap) + if !code.disableIndirectConversion && !indirect && isPtr { + code.enableIndirect() + } + delete(c.structTypeToCode, typeptr) + return code, nil +} + +func toElemType(t *runtime.Type) *runtime.Type { + for t.Kind() == reflect.Ptr { + t = t.Elem() + } + return t +} + +func (c *Compiler) structFieldCode(structCode *StructCode, tag *runtime.StructTag, isPtr, isOnlyOneFirstField bool) (*StructFieldCode, error) { + field := tag.Field + fieldType := runtime.Type2RType(field.Type) + isIndirectSpecialCase := isPtr && isOnlyOneFirstField + fieldCode := &StructFieldCode{ + typ: fieldType, + key: tag.Key, + tag: tag, + offset: field.Offset, + isAnonymous: field.Anonymous && !tag.IsTaggedKey && toElemType(fieldType).Kind() == reflect.Struct, + isTaggedKey: tag.IsTaggedKey, + isNilableType: c.isNilableType(fieldType), + isNilCheck: true, + } + switch { + case c.isMovePointerPositionFromHeadToFirstMarshalJSONFieldCase(fieldType, isIndirectSpecialCase): + code, err := c.marshalJSONCode(fieldType) + if err != nil { + return nil, err + } + fieldCode.value = code + fieldCode.isAddrForMarshaler = true + fieldCode.isNilCheck = false + structCode.isIndirect = false + structCode.disableIndirectConversion = true + case c.isMovePointerPositionFromHeadToFirstMarshalTextFieldCase(fieldType, isIndirectSpecialCase): + code, err := c.marshalTextCode(fieldType) + if err != nil { + return nil, err + } + fieldCode.value = code + fieldCode.isAddrForMarshaler = true + fieldCode.isNilCheck = false + structCode.isIndirect = false + structCode.disableIndirectConversion = true + case isPtr && c.isPtrMarshalJSONType(fieldType): + // *struct{ field T } + // func (*T) MarshalJSON() ([]byte, error) + code, err := c.marshalJSONCode(fieldType) + if err != nil { + return nil, err + } + fieldCode.value = code + fieldCode.isAddrForMarshaler = true + fieldCode.isNilCheck = false + case isPtr && c.isPtrMarshalTextType(fieldType): + // *struct{ field T } + // func (*T) MarshalText() ([]byte, error) + code, err := c.marshalTextCode(fieldType) + if err != nil { + return nil, err + } + fieldCode.value = code + fieldCode.isAddrForMarshaler = true + fieldCode.isNilCheck = false + default: + code, err := c.typeToCodeWithPtr(fieldType, isPtr) + if err != nil { + return nil, err + } + switch code.Kind() { + case CodeKindPtr, CodeKindInterface: + fieldCode.isNextOpPtrType = true + } + fieldCode.value = code + } + return fieldCode, nil +} + +func (c *Compiler) isAssignableIndirect(fieldCode *StructFieldCode, isPtr bool) bool { + if isPtr { + return false + } + codeType := fieldCode.value.Kind() + if codeType == CodeKindMarshalJSON { + return false + } + if codeType == CodeKindMarshalText { + return false + } + return true +} + +func (c *Compiler) getFieldMap(fields []*StructFieldCode) map[string][]*StructFieldCode { + fieldMap := map[string][]*StructFieldCode{} + for _, field := range fields { + if field.isAnonymous { + for k, v := range c.getAnonymousFieldMap(field) { + fieldMap[k] = append(fieldMap[k], v...) + } + continue + } + fieldMap[field.key] = append(fieldMap[field.key], field) + } + return fieldMap +} + +func (c *Compiler) getAnonymousFieldMap(field *StructFieldCode) map[string][]*StructFieldCode { + fieldMap := map[string][]*StructFieldCode{} + structCode := field.getAnonymousStruct() + if structCode == nil || structCode.isRecursive { + fieldMap[field.key] = append(fieldMap[field.key], field) + return fieldMap + } + for k, v := range c.getFieldMapFromAnonymousParent(structCode.fields) { + fieldMap[k] = append(fieldMap[k], v...) + } + return fieldMap +} + +func (c *Compiler) getFieldMapFromAnonymousParent(fields []*StructFieldCode) map[string][]*StructFieldCode { + fieldMap := map[string][]*StructFieldCode{} + for _, field := range fields { + if field.isAnonymous { + for k, v := range c.getAnonymousFieldMap(field) { + // Do not handle tagged key when embedding more than once + for _, vv := range v { + vv.isTaggedKey = false + } + fieldMap[k] = append(fieldMap[k], v...) + } + continue + } + fieldMap[field.key] = append(fieldMap[field.key], field) + } + return fieldMap +} + +func (c *Compiler) getDuplicatedFieldMap(fieldMap map[string][]*StructFieldCode) map[*StructFieldCode]struct{} { + duplicatedFieldMap := map[*StructFieldCode]struct{}{} + for _, fields := range fieldMap { + if len(fields) == 1 { + continue + } + if c.isTaggedKeyOnly(fields) { + for _, field := range fields { + if field.isTaggedKey { + continue + } + duplicatedFieldMap[field] = struct{}{} + } + } else { + for _, field := range fields { + duplicatedFieldMap[field] = struct{}{} + } + } + } + return duplicatedFieldMap +} + +func (c *Compiler) filteredDuplicatedFields(fields []*StructFieldCode, duplicatedFieldMap map[*StructFieldCode]struct{}) []*StructFieldCode { + filteredFields := make([]*StructFieldCode, 0, len(fields)) + for _, field := range fields { + if field.isAnonymous { + structCode := field.getAnonymousStruct() + if structCode != nil && !structCode.isRecursive { + structCode.fields = c.filteredDuplicatedFields(structCode.fields, duplicatedFieldMap) + if len(structCode.fields) > 0 { + filteredFields = append(filteredFields, field) + } + continue + } + } + if _, exists := duplicatedFieldMap[field]; exists { + continue + } + filteredFields = append(filteredFields, field) + } + return filteredFields +} + +func (c *Compiler) isTaggedKeyOnly(fields []*StructFieldCode) bool { + var taggedKeyFieldCount int + for _, field := range fields { + if field.isTaggedKey { + taggedKeyFieldCount++ + } + } + return taggedKeyFieldCount == 1 +} + +func (c *Compiler) typeToStructTags(typ *runtime.Type) runtime.StructTags { + tags := runtime.StructTags{} + fieldNum := typ.NumField() + for i := 0; i < fieldNum; i++ { + field := typ.Field(i) + if runtime.IsIgnoredStructField(field) { + continue + } + tags = append(tags, runtime.StructTagFromField(field)) + } + return tags +} + +// *struct{ field T } => struct { field *T } +// func (*T) MarshalJSON() ([]byte, error) +func (c *Compiler) isMovePointerPositionFromHeadToFirstMarshalJSONFieldCase(typ *runtime.Type, isIndirectSpecialCase bool) bool { + return isIndirectSpecialCase && !c.isNilableType(typ) && c.isPtrMarshalJSONType(typ) +} + +// *struct{ field T } => struct { field *T } +// func (*T) MarshalText() ([]byte, error) +func (c *Compiler) isMovePointerPositionFromHeadToFirstMarshalTextFieldCase(typ *runtime.Type, isIndirectSpecialCase bool) bool { + return isIndirectSpecialCase && !c.isNilableType(typ) && c.isPtrMarshalTextType(typ) +} + +func (c *Compiler) implementsMarshalJSON(typ *runtime.Type) bool { + if !c.implementsMarshalJSONType(typ) { + return false + } + if typ.Kind() != reflect.Ptr { + return true + } + // type kind is reflect.Ptr + if !c.implementsMarshalJSONType(typ.Elem()) { + return true + } + // needs to dereference + return false +} + +func (c *Compiler) implementsMarshalText(typ *runtime.Type) bool { + if !typ.Implements(marshalTextType) { + return false + } + if typ.Kind() != reflect.Ptr { + return true + } + // type kind is reflect.Ptr + if !typ.Elem().Implements(marshalTextType) { + return true + } + // needs to dereference + return false +} + +func (c *Compiler) isNilableType(typ *runtime.Type) bool { + if !runtime.IfaceIndir(typ) { + return true + } + switch typ.Kind() { + case reflect.Ptr: + return true + case reflect.Map: + return true + case reflect.Func: + return true + default: + return false + } +} + +func (c *Compiler) implementsMarshalJSONType(typ *runtime.Type) bool { + return typ.Implements(marshalJSONType) || typ.Implements(marshalJSONContextType) +} + +func (c *Compiler) isPtrMarshalJSONType(typ *runtime.Type) bool { + return !c.implementsMarshalJSONType(typ) && c.implementsMarshalJSONType(runtime.PtrTo(typ)) +} + +func (c *Compiler) isPtrMarshalTextType(typ *runtime.Type) bool { + return !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType) +} + +func (c *Compiler) codeToOpcode(ctx *compileContext, typ *runtime.Type, code Code) *Opcode { + codes := code.ToOpcode(ctx) + codes.Last().Next = newEndOp(ctx, typ) + c.linkRecursiveCode(ctx) + return codes.First() +} + +func (c *Compiler) linkRecursiveCode(ctx *compileContext) { + recursiveCodes := map[uintptr]*CompiledCode{} + for _, recursive := range *ctx.recursiveCodes { + typeptr := uintptr(unsafe.Pointer(recursive.Type)) + codes := ctx.structTypeToCodes[typeptr] + if recursiveCode, ok := recursiveCodes[typeptr]; ok { + *recursive.Jmp = *recursiveCode + continue + } + + code := copyOpcode(codes.First()) + code.Op = code.Op.PtrHeadToHead() + lastCode := newEndOp(&compileContext{}, recursive.Type) + lastCode.Op = OpRecursiveEnd + + // OpRecursiveEnd must set before call TotalLength + code.End.Next = lastCode + + totalLength := code.TotalLength() + + // Idx, ElemIdx, Length must set after call TotalLength + lastCode.Idx = uint32((totalLength + 1) * uintptrSize) + lastCode.ElemIdx = lastCode.Idx + uintptrSize + lastCode.Length = lastCode.Idx + 2*uintptrSize + + // extend length to alloc slot for elemIdx + length + curTotalLength := uintptr(recursive.TotalLength()) + 3 + nextTotalLength := uintptr(totalLength) + 3 + + compiled := recursive.Jmp + compiled.Code = code + compiled.CurLen = curTotalLength + compiled.NextLen = nextTotalLength + compiled.Linked = true + + recursiveCodes[typeptr] = compiled + } +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go b/vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go new file mode 100644 index 000000000..20c93cbf7 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go @@ -0,0 +1,32 @@ +//go:build !race +// +build !race + +package encoder + +func CompileToGetCodeSet(ctx *RuntimeContext, typeptr uintptr) (*OpcodeSet, error) { + if typeptr > typeAddr.MaxTypeAddr || typeptr < typeAddr.BaseTypeAddr { + codeSet, err := compileToGetCodeSetSlowPath(typeptr) + if err != nil { + return nil, err + } + return getFilteredCodeSetIfNeeded(ctx, codeSet) + } + index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift + if codeSet := cachedOpcodeSets[index]; codeSet != nil { + filtered, err := getFilteredCodeSetIfNeeded(ctx, codeSet) + if err != nil { + return nil, err + } + return filtered, nil + } + codeSet, err := newCompiler().compile(typeptr) + if err != nil { + return nil, err + } + filtered, err := getFilteredCodeSetIfNeeded(ctx, codeSet) + if err != nil { + return nil, err + } + cachedOpcodeSets[index] = codeSet + return filtered, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go b/vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go new file mode 100644 index 000000000..13ba23fdf --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go @@ -0,0 +1,45 @@ +//go:build race +// +build race + +package encoder + +import ( + "sync" +) + +var setsMu sync.RWMutex + +func CompileToGetCodeSet(ctx *RuntimeContext, typeptr uintptr) (*OpcodeSet, error) { + if typeptr > typeAddr.MaxTypeAddr || typeptr < typeAddr.BaseTypeAddr { + codeSet, err := compileToGetCodeSetSlowPath(typeptr) + if err != nil { + return nil, err + } + return getFilteredCodeSetIfNeeded(ctx, codeSet) + } + index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift + setsMu.RLock() + if codeSet := cachedOpcodeSets[index]; codeSet != nil { + filtered, err := getFilteredCodeSetIfNeeded(ctx, codeSet) + if err != nil { + setsMu.RUnlock() + return nil, err + } + setsMu.RUnlock() + return filtered, nil + } + setsMu.RUnlock() + + codeSet, err := newCompiler().compile(typeptr) + if err != nil { + return nil, err + } + filtered, err := getFilteredCodeSetIfNeeded(ctx, codeSet) + if err != nil { + return nil, err + } + setsMu.Lock() + cachedOpcodeSets[index] = codeSet + setsMu.Unlock() + return filtered, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/context.go b/vendor/github.com/goccy/go-json/internal/encoder/context.go new file mode 100644 index 000000000..3833d0c86 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/context.go @@ -0,0 +1,105 @@ +package encoder + +import ( + "context" + "sync" + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +type compileContext struct { + opcodeIndex uint32 + ptrIndex int + indent uint32 + escapeKey bool + structTypeToCodes map[uintptr]Opcodes + recursiveCodes *Opcodes +} + +func (c *compileContext) incIndent() { + c.indent++ +} + +func (c *compileContext) decIndent() { + c.indent-- +} + +func (c *compileContext) incIndex() { + c.incOpcodeIndex() + c.incPtrIndex() +} + +func (c *compileContext) decIndex() { + c.decOpcodeIndex() + c.decPtrIndex() +} + +func (c *compileContext) incOpcodeIndex() { + c.opcodeIndex++ +} + +func (c *compileContext) decOpcodeIndex() { + c.opcodeIndex-- +} + +func (c *compileContext) incPtrIndex() { + c.ptrIndex++ +} + +func (c *compileContext) decPtrIndex() { + c.ptrIndex-- +} + +const ( + bufSize = 1024 +) + +var ( + runtimeContextPool = sync.Pool{ + New: func() interface{} { + return &RuntimeContext{ + Buf: make([]byte, 0, bufSize), + Ptrs: make([]uintptr, 128), + KeepRefs: make([]unsafe.Pointer, 0, 8), + Option: &Option{}, + } + }, + } +) + +type RuntimeContext struct { + Context context.Context + Buf []byte + MarshalBuf []byte + Ptrs []uintptr + KeepRefs []unsafe.Pointer + SeenPtr []uintptr + BaseIndent uint32 + Prefix []byte + IndentStr []byte + Option *Option +} + +func (c *RuntimeContext) Init(p uintptr, codelen int) { + if len(c.Ptrs) < codelen { + c.Ptrs = make([]uintptr, codelen) + } + c.Ptrs[0] = p + c.KeepRefs = c.KeepRefs[:0] + c.SeenPtr = c.SeenPtr[:0] + c.BaseIndent = 0 +} + +func (c *RuntimeContext) Ptr() uintptr { + header := (*runtime.SliceHeader)(unsafe.Pointer(&c.Ptrs)) + return uintptr(header.Data) +} + +func TakeRuntimeContext() *RuntimeContext { + return runtimeContextPool.Get().(*RuntimeContext) +} + +func ReleaseRuntimeContext(ctx *RuntimeContext) { + runtimeContextPool.Put(ctx) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/decode_rune.go b/vendor/github.com/goccy/go-json/internal/encoder/decode_rune.go new file mode 100644 index 000000000..35c959d48 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/decode_rune.go @@ -0,0 +1,126 @@ +package encoder + +import "unicode/utf8" + +const ( + // The default lowest and highest continuation byte. + locb = 128 //0b10000000 + hicb = 191 //0b10111111 + + // These names of these constants are chosen to give nice alignment in the + // table below. The first nibble is an index into acceptRanges or F for + // special one-byte cases. The second nibble is the Rune length or the + // Status for the special one-byte case. + xx = 0xF1 // invalid: size 1 + as = 0xF0 // ASCII: size 1 + s1 = 0x02 // accept 0, size 2 + s2 = 0x13 // accept 1, size 3 + s3 = 0x03 // accept 0, size 3 + s4 = 0x23 // accept 2, size 3 + s5 = 0x34 // accept 3, size 4 + s6 = 0x04 // accept 0, size 4 + s7 = 0x44 // accept 4, size 4 +) + +// first is information about the first byte in a UTF-8 sequence. +var first = [256]uint8{ + // 1 2 3 4 5 6 7 8 9 A B C D E F + as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x00-0x0F + as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x10-0x1F + as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x20-0x2F + as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x30-0x3F + as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x40-0x4F + as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x50-0x5F + as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x60-0x6F + as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x70-0x7F + // 1 2 3 4 5 6 7 8 9 A B C D E F + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x80-0x8F + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x90-0x9F + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xA0-0xAF + xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xB0-0xBF + xx, xx, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xC0-0xCF + s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xD0-0xDF + s2, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s4, s3, s3, // 0xE0-0xEF + s5, s6, s6, s6, s7, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xF0-0xFF +} + +const ( + lineSep = byte(168) //'\u2028' + paragraphSep = byte(169) //'\u2029' +) + +type decodeRuneState int + +const ( + validUTF8State decodeRuneState = iota + runeErrorState + lineSepState + paragraphSepState +) + +func decodeRuneInString(s string) (decodeRuneState, int) { + n := len(s) + s0 := s[0] + x := first[s0] + if x >= as { + // The following code simulates an additional check for x == xx and + // handling the ASCII and invalid cases accordingly. This mask-and-or + // approach prevents an additional branch. + mask := rune(x) << 31 >> 31 // Create 0x0000 or 0xFFFF. + if rune(s[0])&^mask|utf8.RuneError&mask == utf8.RuneError { + return runeErrorState, 1 + } + return validUTF8State, 1 + } + sz := int(x & 7) + if n < sz { + return runeErrorState, 1 + } + s1 := s[1] + switch x >> 4 { + case 0: + if s1 < locb || hicb < s1 { + return runeErrorState, 1 + } + case 1: + if s1 < 0xA0 || hicb < s1 { + return runeErrorState, 1 + } + case 2: + if s1 < locb || 0x9F < s1 { + return runeErrorState, 1 + } + case 3: + if s1 < 0x90 || hicb < s1 { + return runeErrorState, 1 + } + case 4: + if s1 < locb || 0x8F < s1 { + return runeErrorState, 1 + } + } + if sz <= 2 { + return validUTF8State, 2 + } + s2 := s[2] + if s2 < locb || hicb < s2 { + return runeErrorState, 1 + } + if sz <= 3 { + // separator character prefixes: [2]byte{226, 128} + if s0 == 226 && s1 == 128 { + switch s2 { + case lineSep: + return lineSepState, 3 + case paragraphSep: + return paragraphSepState, 3 + } + } + return validUTF8State, 3 + } + s3 := s[3] + if s3 < locb || hicb < s3 { + return runeErrorState, 1 + } + return validUTF8State, 4 +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/encoder.go b/vendor/github.com/goccy/go-json/internal/encoder/encoder.go new file mode 100644 index 000000000..14eb6a0d6 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/encoder.go @@ -0,0 +1,596 @@ +package encoder + +import ( + "bytes" + "encoding" + "encoding/base64" + "encoding/json" + "fmt" + "math" + "reflect" + "strconv" + "strings" + "sync" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +func (t OpType) IsMultipleOpHead() bool { + switch t { + case OpStructHead: + return true + case OpStructHeadSlice: + return true + case OpStructHeadArray: + return true + case OpStructHeadMap: + return true + case OpStructHeadStruct: + return true + case OpStructHeadOmitEmpty: + return true + case OpStructHeadOmitEmptySlice: + return true + case OpStructHeadOmitEmptyArray: + return true + case OpStructHeadOmitEmptyMap: + return true + case OpStructHeadOmitEmptyStruct: + return true + case OpStructHeadSlicePtr: + return true + case OpStructHeadOmitEmptySlicePtr: + return true + case OpStructHeadArrayPtr: + return true + case OpStructHeadOmitEmptyArrayPtr: + return true + case OpStructHeadMapPtr: + return true + case OpStructHeadOmitEmptyMapPtr: + return true + } + return false +} + +func (t OpType) IsMultipleOpField() bool { + switch t { + case OpStructField: + return true + case OpStructFieldSlice: + return true + case OpStructFieldArray: + return true + case OpStructFieldMap: + return true + case OpStructFieldStruct: + return true + case OpStructFieldOmitEmpty: + return true + case OpStructFieldOmitEmptySlice: + return true + case OpStructFieldOmitEmptyArray: + return true + case OpStructFieldOmitEmptyMap: + return true + case OpStructFieldOmitEmptyStruct: + return true + case OpStructFieldSlicePtr: + return true + case OpStructFieldOmitEmptySlicePtr: + return true + case OpStructFieldArrayPtr: + return true + case OpStructFieldOmitEmptyArrayPtr: + return true + case OpStructFieldMapPtr: + return true + case OpStructFieldOmitEmptyMapPtr: + return true + } + return false +} + +type OpcodeSet struct { + Type *runtime.Type + NoescapeKeyCode *Opcode + EscapeKeyCode *Opcode + InterfaceNoescapeKeyCode *Opcode + InterfaceEscapeKeyCode *Opcode + CodeLength int + EndCode *Opcode + Code Code + QueryCache map[string]*OpcodeSet + cacheMu sync.RWMutex +} + +func (s *OpcodeSet) getQueryCache(hash string) *OpcodeSet { + s.cacheMu.RLock() + codeSet := s.QueryCache[hash] + s.cacheMu.RUnlock() + return codeSet +} + +func (s *OpcodeSet) setQueryCache(hash string, codeSet *OpcodeSet) { + s.cacheMu.Lock() + s.QueryCache[hash] = codeSet + s.cacheMu.Unlock() +} + +type CompiledCode struct { + Code *Opcode + Linked bool // whether recursive code already have linked + CurLen uintptr + NextLen uintptr +} + +const StartDetectingCyclesAfter = 1000 + +func Load(base uintptr, idx uintptr) uintptr { + addr := base + idx + return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func Store(base uintptr, idx uintptr, p uintptr) { + addr := base + idx + **(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func LoadNPtr(base uintptr, idx uintptr, ptrNum int) uintptr { + addr := base + idx + p := **(**uintptr)(unsafe.Pointer(&addr)) + if p == 0 { + return 0 + } + return PtrToPtr(p) + /* + for i := 0; i < ptrNum; i++ { + if p == 0 { + return p + } + p = PtrToPtr(p) + } + return p + */ +} + +func PtrToUint64(p uintptr) uint64 { return **(**uint64)(unsafe.Pointer(&p)) } +func PtrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func PtrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func PtrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func PtrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func PtrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) } +func PtrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) } +func PtrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func PtrToPtr(p uintptr) uintptr { + return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func PtrToNPtr(p uintptr, ptrNum int) uintptr { + for i := 0; i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = PtrToPtr(p) + } + return p +} + +func PtrToUnsafePtr(p uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func PtrToInterface(code *Opcode, p uintptr) interface{} { + return *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) +} + +func ErrUnsupportedValue(code *Opcode, ptr uintptr) *errors.UnsupportedValueError { + v := *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)), + })) + return &errors.UnsupportedValueError{ + Value: reflect.ValueOf(v), + Str: fmt.Sprintf("encountered a cycle via %s", code.Type), + } +} + +func ErrUnsupportedFloat(v float64) *errors.UnsupportedValueError { + return &errors.UnsupportedValueError{ + Value: reflect.ValueOf(v), + Str: strconv.FormatFloat(v, 'g', -1, 64), + } +} + +func ErrMarshalerWithCode(code *Opcode, err error) *errors.MarshalerError { + return &errors.MarshalerError{ + Type: runtime.RType2Type(code.Type), + Err: err, + } +} + +type emptyInterface struct { + typ *runtime.Type + ptr unsafe.Pointer +} + +type MapItem struct { + Key []byte + Value []byte +} + +type Mapslice struct { + Items []MapItem +} + +func (m *Mapslice) Len() int { + return len(m.Items) +} + +func (m *Mapslice) Less(i, j int) bool { + return bytes.Compare(m.Items[i].Key, m.Items[j].Key) < 0 +} + +func (m *Mapslice) Swap(i, j int) { + m.Items[i], m.Items[j] = m.Items[j], m.Items[i] +} + +//nolint:structcheck,unused +type mapIter struct { + key unsafe.Pointer + elem unsafe.Pointer + t unsafe.Pointer + h unsafe.Pointer + buckets unsafe.Pointer + bptr unsafe.Pointer + overflow unsafe.Pointer + oldoverflow unsafe.Pointer + startBucket uintptr + offset uint8 + wrapped bool + B uint8 + i uint8 + bucket uintptr + checkBucket uintptr +} + +type MapContext struct { + Start int + First int + Idx int + Slice *Mapslice + Buf []byte + Len int + Iter mapIter +} + +var mapContextPool = sync.Pool{ + New: func() interface{} { + return &MapContext{ + Slice: &Mapslice{}, + } + }, +} + +func NewMapContext(mapLen int, unorderedMap bool) *MapContext { + ctx := mapContextPool.Get().(*MapContext) + if !unorderedMap { + if len(ctx.Slice.Items) < mapLen { + ctx.Slice.Items = make([]MapItem, mapLen) + } else { + ctx.Slice.Items = ctx.Slice.Items[:mapLen] + } + } + ctx.Buf = ctx.Buf[:0] + ctx.Iter = mapIter{} + ctx.Idx = 0 + ctx.Len = mapLen + return ctx +} + +func ReleaseMapContext(c *MapContext) { + mapContextPool.Put(c) +} + +//go:linkname MapIterInit runtime.mapiterinit +//go:noescape +func MapIterInit(mapType *runtime.Type, m unsafe.Pointer, it *mapIter) + +//go:linkname MapIterKey reflect.mapiterkey +//go:noescape +func MapIterKey(it *mapIter) unsafe.Pointer + +//go:linkname MapIterNext reflect.mapiternext +//go:noescape +func MapIterNext(it *mapIter) + +//go:linkname MapLen reflect.maplen +//go:noescape +func MapLen(m unsafe.Pointer) int + +func AppendByteSlice(_ *RuntimeContext, b []byte, src []byte) []byte { + if src == nil { + return append(b, `null`...) + } + encodedLen := base64.StdEncoding.EncodedLen(len(src)) + b = append(b, '"') + pos := len(b) + remainLen := cap(b[pos:]) + var buf []byte + if remainLen > encodedLen { + buf = b[pos : pos+encodedLen] + } else { + buf = make([]byte, encodedLen) + } + base64.StdEncoding.Encode(buf, src) + return append(append(b, buf...), '"') +} + +func AppendFloat32(_ *RuntimeContext, b []byte, v float32) []byte { + f64 := float64(v) + abs := math.Abs(f64) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + f32 := float32(abs) + if f32 < 1e-6 || f32 >= 1e21 { + fmt = 'e' + } + } + return strconv.AppendFloat(b, f64, fmt, -1, 32) +} + +func AppendFloat64(_ *RuntimeContext, b []byte, v float64) []byte { + abs := math.Abs(v) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + if abs < 1e-6 || abs >= 1e21 { + fmt = 'e' + } + } + return strconv.AppendFloat(b, v, fmt, -1, 64) +} + +func AppendBool(_ *RuntimeContext, b []byte, v bool) []byte { + if v { + return append(b, "true"...) + } + return append(b, "false"...) +} + +var ( + floatTable = [256]bool{ + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + '.': true, + 'e': true, + 'E': true, + '+': true, + '-': true, + } +) + +func AppendNumber(_ *RuntimeContext, b []byte, n json.Number) ([]byte, error) { + if len(n) == 0 { + return append(b, '0'), nil + } + for i := 0; i < len(n); i++ { + if !floatTable[n[i]] { + return nil, fmt.Errorf("json: invalid number literal %q", n) + } + } + b = append(b, n...) + return b, nil +} + +func AppendMarshalJSON(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) { + rv := reflect.ValueOf(v) // convert by dynamic interface type + if (code.Flags & AddrForMarshalerFlags) != 0 { + if rv.CanAddr() { + rv = rv.Addr() + } else { + newV := reflect.New(rv.Type()) + newV.Elem().Set(rv) + rv = newV + } + } + v = rv.Interface() + var bb []byte + if (code.Flags & MarshalerContextFlags) != 0 { + marshaler, ok := v.(marshalerContext) + if !ok { + return AppendNull(ctx, b), nil + } + stdctx := ctx.Option.Context + if ctx.Option.Flag&FieldQueryOption != 0 { + stdctx = SetFieldQueryToContext(stdctx, code.FieldQuery) + } + b, err := marshaler.MarshalJSON(stdctx) + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + bb = b + } else { + marshaler, ok := v.(json.Marshaler) + if !ok { + return AppendNull(ctx, b), nil + } + b, err := marshaler.MarshalJSON() + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + bb = b + } + marshalBuf := ctx.MarshalBuf[:0] + marshalBuf = append(append(marshalBuf, bb...), nul) + compactedBuf, err := compact(b, marshalBuf, (ctx.Option.Flag&HTMLEscapeOption) != 0) + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + ctx.MarshalBuf = marshalBuf + return compactedBuf, nil +} + +func AppendMarshalJSONIndent(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) { + rv := reflect.ValueOf(v) // convert by dynamic interface type + if (code.Flags & AddrForMarshalerFlags) != 0 { + if rv.CanAddr() { + rv = rv.Addr() + } else { + newV := reflect.New(rv.Type()) + newV.Elem().Set(rv) + rv = newV + } + } + v = rv.Interface() + var bb []byte + if (code.Flags & MarshalerContextFlags) != 0 { + marshaler, ok := v.(marshalerContext) + if !ok { + return AppendNull(ctx, b), nil + } + b, err := marshaler.MarshalJSON(ctx.Option.Context) + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + bb = b + } else { + marshaler, ok := v.(json.Marshaler) + if !ok { + return AppendNull(ctx, b), nil + } + b, err := marshaler.MarshalJSON() + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + bb = b + } + marshalBuf := ctx.MarshalBuf[:0] + marshalBuf = append(append(marshalBuf, bb...), nul) + indentedBuf, err := doIndent( + b, + marshalBuf, + string(ctx.Prefix)+strings.Repeat(string(ctx.IndentStr), int(ctx.BaseIndent+code.Indent)), + string(ctx.IndentStr), + (ctx.Option.Flag&HTMLEscapeOption) != 0, + ) + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + ctx.MarshalBuf = marshalBuf + return indentedBuf, nil +} + +func AppendMarshalText(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) { + rv := reflect.ValueOf(v) // convert by dynamic interface type + if (code.Flags & AddrForMarshalerFlags) != 0 { + if rv.CanAddr() { + rv = rv.Addr() + } else { + newV := reflect.New(rv.Type()) + newV.Elem().Set(rv) + rv = newV + } + } + v = rv.Interface() + marshaler, ok := v.(encoding.TextMarshaler) + if !ok { + return AppendNull(ctx, b), nil + } + bytes, err := marshaler.MarshalText() + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + return AppendString(ctx, b, *(*string)(unsafe.Pointer(&bytes))), nil +} + +func AppendMarshalTextIndent(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) { + rv := reflect.ValueOf(v) // convert by dynamic interface type + if (code.Flags & AddrForMarshalerFlags) != 0 { + if rv.CanAddr() { + rv = rv.Addr() + } else { + newV := reflect.New(rv.Type()) + newV.Elem().Set(rv) + rv = newV + } + } + v = rv.Interface() + marshaler, ok := v.(encoding.TextMarshaler) + if !ok { + return AppendNull(ctx, b), nil + } + bytes, err := marshaler.MarshalText() + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + return AppendString(ctx, b, *(*string)(unsafe.Pointer(&bytes))), nil +} + +func AppendNull(_ *RuntimeContext, b []byte) []byte { + return append(b, "null"...) +} + +func AppendComma(_ *RuntimeContext, b []byte) []byte { + return append(b, ',') +} + +func AppendCommaIndent(_ *RuntimeContext, b []byte) []byte { + return append(b, ',', '\n') +} + +func AppendStructEnd(_ *RuntimeContext, b []byte) []byte { + return append(b, '}', ',') +} + +func AppendStructEndIndent(ctx *RuntimeContext, code *Opcode, b []byte) []byte { + b = append(b, '\n') + b = append(b, ctx.Prefix...) + indentNum := ctx.BaseIndent + code.Indent - 1 + for i := uint32(0); i < indentNum; i++ { + b = append(b, ctx.IndentStr...) + } + return append(b, '}', ',', '\n') +} + +func AppendIndent(ctx *RuntimeContext, b []byte, indent uint32) []byte { + b = append(b, ctx.Prefix...) + indentNum := ctx.BaseIndent + indent + for i := uint32(0); i < indentNum; i++ { + b = append(b, ctx.IndentStr...) + } + return b +} + +func IsNilForMarshaler(v interface{}) bool { + rv := reflect.ValueOf(v) + switch rv.Kind() { + case reflect.Bool: + return !rv.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return rv.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return rv.Uint() == 0 + case reflect.Float32, reflect.Float64: + return math.Float64bits(rv.Float()) == 0 + case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Func: + return rv.IsNil() + case reflect.Slice: + return rv.IsNil() || rv.Len() == 0 + case reflect.String: + return rv.Len() == 0 + } + return false +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/indent.go b/vendor/github.com/goccy/go-json/internal/encoder/indent.go new file mode 100644 index 000000000..dfe04b5e3 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/indent.go @@ -0,0 +1,211 @@ +package encoder + +import ( + "bytes" + "fmt" + + "github.com/goccy/go-json/internal/errors" +) + +func takeIndentSrcRuntimeContext(src []byte) (*RuntimeContext, []byte) { + ctx := TakeRuntimeContext() + buf := ctx.Buf[:0] + buf = append(append(buf, src...), nul) + ctx.Buf = buf + return ctx, buf +} + +func Indent(buf *bytes.Buffer, src []byte, prefix, indentStr string) error { + if len(src) == 0 { + return errors.ErrUnexpectedEndOfJSON("", 0) + } + + srcCtx, srcBuf := takeIndentSrcRuntimeContext(src) + dstCtx := TakeRuntimeContext() + dst := dstCtx.Buf[:0] + + dst, err := indentAndWrite(buf, dst, srcBuf, prefix, indentStr) + if err != nil { + ReleaseRuntimeContext(srcCtx) + ReleaseRuntimeContext(dstCtx) + return err + } + dstCtx.Buf = dst + ReleaseRuntimeContext(srcCtx) + ReleaseRuntimeContext(dstCtx) + return nil +} + +func indentAndWrite(buf *bytes.Buffer, dst []byte, src []byte, prefix, indentStr string) ([]byte, error) { + dst, err := doIndent(dst, src, prefix, indentStr, false) + if err != nil { + return nil, err + } + if _, err := buf.Write(dst); err != nil { + return nil, err + } + return dst, nil +} + +func doIndent(dst, src []byte, prefix, indentStr string, escape bool) ([]byte, error) { + buf, cursor, err := indentValue(dst, src, 0, 0, []byte(prefix), []byte(indentStr), escape) + if err != nil { + return nil, err + } + if err := validateEndBuf(src, cursor); err != nil { + return nil, err + } + return buf, nil +} + +func indentValue( + dst []byte, + src []byte, + indentNum int, + cursor int64, + prefix []byte, + indentBytes []byte, + escape bool) ([]byte, int64, error) { + for { + switch src[cursor] { + case ' ', '\t', '\n', '\r': + cursor++ + continue + case '{': + return indentObject(dst, src, indentNum, cursor, prefix, indentBytes, escape) + case '}': + return nil, 0, errors.ErrSyntax("unexpected character '}'", cursor) + case '[': + return indentArray(dst, src, indentNum, cursor, prefix, indentBytes, escape) + case ']': + return nil, 0, errors.ErrSyntax("unexpected character ']'", cursor) + case '"': + return compactString(dst, src, cursor, escape) + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return compactNumber(dst, src, cursor) + case 't': + return compactTrue(dst, src, cursor) + case 'f': + return compactFalse(dst, src, cursor) + case 'n': + return compactNull(dst, src, cursor) + default: + return nil, 0, errors.ErrSyntax(fmt.Sprintf("unexpected character '%c'", src[cursor]), cursor) + } + } +} + +func indentObject( + dst []byte, + src []byte, + indentNum int, + cursor int64, + prefix []byte, + indentBytes []byte, + escape bool) ([]byte, int64, error) { + if src[cursor] == '{' { + dst = append(dst, '{') + } else { + return nil, 0, errors.ErrExpected("expected { character for object value", cursor) + } + cursor = skipWhiteSpace(src, cursor+1) + if src[cursor] == '}' { + dst = append(dst, '}') + return dst, cursor + 1, nil + } + indentNum++ + var err error + for { + dst = append(append(dst, '\n'), prefix...) + for i := 0; i < indentNum; i++ { + dst = append(dst, indentBytes...) + } + cursor = skipWhiteSpace(src, cursor) + dst, cursor, err = compactString(dst, src, cursor, escape) + if err != nil { + return nil, 0, err + } + cursor = skipWhiteSpace(src, cursor) + if src[cursor] != ':' { + return nil, 0, errors.ErrSyntax( + fmt.Sprintf("invalid character '%c' after object key", src[cursor]), + cursor+1, + ) + } + dst = append(dst, ':', ' ') + dst, cursor, err = indentValue(dst, src, indentNum, cursor+1, prefix, indentBytes, escape) + if err != nil { + return nil, 0, err + } + cursor = skipWhiteSpace(src, cursor) + switch src[cursor] { + case '}': + dst = append(append(dst, '\n'), prefix...) + for i := 0; i < indentNum-1; i++ { + dst = append(dst, indentBytes...) + } + dst = append(dst, '}') + cursor++ + return dst, cursor, nil + case ',': + dst = append(dst, ',') + default: + return nil, 0, errors.ErrSyntax( + fmt.Sprintf("invalid character '%c' after object key:value pair", src[cursor]), + cursor+1, + ) + } + cursor++ + } +} + +func indentArray( + dst []byte, + src []byte, + indentNum int, + cursor int64, + prefix []byte, + indentBytes []byte, + escape bool) ([]byte, int64, error) { + if src[cursor] == '[' { + dst = append(dst, '[') + } else { + return nil, 0, errors.ErrExpected("expected [ character for array value", cursor) + } + cursor = skipWhiteSpace(src, cursor+1) + if src[cursor] == ']' { + dst = append(dst, ']') + return dst, cursor + 1, nil + } + indentNum++ + var err error + for { + dst = append(append(dst, '\n'), prefix...) + for i := 0; i < indentNum; i++ { + dst = append(dst, indentBytes...) + } + dst, cursor, err = indentValue(dst, src, indentNum, cursor, prefix, indentBytes, escape) + if err != nil { + return nil, 0, err + } + cursor = skipWhiteSpace(src, cursor) + switch src[cursor] { + case ']': + dst = append(append(dst, '\n'), prefix...) + for i := 0; i < indentNum-1; i++ { + dst = append(dst, indentBytes...) + } + dst = append(dst, ']') + cursor++ + return dst, cursor, nil + case ',': + dst = append(dst, ',') + default: + return nil, 0, errors.ErrSyntax( + fmt.Sprintf("invalid character '%c' after array value", src[cursor]), + cursor+1, + ) + } + cursor++ + } +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/int.go b/vendor/github.com/goccy/go-json/internal/encoder/int.go new file mode 100644 index 000000000..85f079609 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/int.go @@ -0,0 +1,152 @@ +package encoder + +import ( + "unsafe" +) + +var endianness int + +func init() { + var b [2]byte + *(*uint16)(unsafe.Pointer(&b)) = uint16(0xABCD) + + switch b[0] { + case 0xCD: + endianness = 0 // LE + case 0xAB: + endianness = 1 // BE + default: + panic("could not determine endianness") + } +} + +// "00010203...96979899" cast to []uint16 +var intLELookup = [100]uint16{ + 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730, 0x3830, 0x3930, + 0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731, 0x3831, 0x3931, + 0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732, 0x3832, 0x3932, + 0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733, 0x3833, 0x3933, + 0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734, 0x3834, 0x3934, + 0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735, 0x3835, 0x3935, + 0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736, 0x3836, 0x3936, + 0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737, 0x3837, 0x3937, + 0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738, 0x3838, 0x3938, + 0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739, 0x3839, 0x3939, +} + +var intBELookup = [100]uint16{ + 0x3030, 0x3031, 0x3032, 0x3033, 0x3034, 0x3035, 0x3036, 0x3037, 0x3038, 0x3039, + 0x3130, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3138, 0x3139, + 0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235, 0x3236, 0x3237, 0x3238, 0x3239, + 0x3330, 0x3331, 0x3332, 0x3333, 0x3334, 0x3335, 0x3336, 0x3337, 0x3338, 0x3339, + 0x3430, 0x3431, 0x3432, 0x3433, 0x3434, 0x3435, 0x3436, 0x3437, 0x3438, 0x3439, + 0x3530, 0x3531, 0x3532, 0x3533, 0x3534, 0x3535, 0x3536, 0x3537, 0x3538, 0x3539, + 0x3630, 0x3631, 0x3632, 0x3633, 0x3634, 0x3635, 0x3636, 0x3637, 0x3638, 0x3639, + 0x3730, 0x3731, 0x3732, 0x3733, 0x3734, 0x3735, 0x3736, 0x3737, 0x3738, 0x3739, + 0x3830, 0x3831, 0x3832, 0x3833, 0x3834, 0x3835, 0x3836, 0x3837, 0x3838, 0x3839, + 0x3930, 0x3931, 0x3932, 0x3933, 0x3934, 0x3935, 0x3936, 0x3937, 0x3938, 0x3939, +} + +var intLookup = [2]*[100]uint16{&intLELookup, &intBELookup} + +func numMask(numBitSize uint8) uint64 { + return 1<>(code.NumBitSize-1))&1 == 1 + if !negative { + if n < 10 { + return append(out, byte(n+'0')) + } else if n < 100 { + u := intLELookup[n] + return append(out, byte(u), byte(u>>8)) + } + } else { + n = -n & mask + } + + lookup := intLookup[endianness] + + var b [22]byte + u := (*[11]uint16)(unsafe.Pointer(&b)) + i := 11 + + for n >= 100 { + j := n % 100 + n /= 100 + i-- + u[i] = lookup[j] + } + + i-- + u[i] = lookup[n] + + i *= 2 // convert to byte index + if n < 10 { + i++ // remove leading zero + } + if negative { + i-- + b[i] = '-' + } + + return append(out, b[i:]...) +} + +func AppendUint(_ *RuntimeContext, out []byte, p uintptr, code *Opcode) []byte { + var u64 uint64 + switch code.NumBitSize { + case 8: + u64 = (uint64)(**(**uint8)(unsafe.Pointer(&p))) + case 16: + u64 = (uint64)(**(**uint16)(unsafe.Pointer(&p))) + case 32: + u64 = (uint64)(**(**uint32)(unsafe.Pointer(&p))) + case 64: + u64 = **(**uint64)(unsafe.Pointer(&p)) + } + mask := numMask(code.NumBitSize) + n := u64 & mask + if n < 10 { + return append(out, byte(n+'0')) + } else if n < 100 { + u := intLELookup[n] + return append(out, byte(u), byte(u>>8)) + } + + lookup := intLookup[endianness] + + var b [22]byte + u := (*[11]uint16)(unsafe.Pointer(&b)) + i := 11 + + for n >= 100 { + j := n % 100 + n /= 100 + i-- + u[i] = lookup[j] + } + + i-- + u[i] = lookup[n] + + i *= 2 // convert to byte index + if n < 10 { + i++ // remove leading zero + } + return append(out, b[i:]...) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/map112.go b/vendor/github.com/goccy/go-json/internal/encoder/map112.go new file mode 100644 index 000000000..e96ffadf7 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/map112.go @@ -0,0 +1,9 @@ +//go:build !go1.13 +// +build !go1.13 + +package encoder + +import "unsafe" + +//go:linkname MapIterValue reflect.mapitervalue +func MapIterValue(it *mapIter) unsafe.Pointer diff --git a/vendor/github.com/goccy/go-json/internal/encoder/map113.go b/vendor/github.com/goccy/go-json/internal/encoder/map113.go new file mode 100644 index 000000000..9b69dcc36 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/map113.go @@ -0,0 +1,9 @@ +//go:build go1.13 +// +build go1.13 + +package encoder + +import "unsafe" + +//go:linkname MapIterValue reflect.mapiterelem +func MapIterValue(it *mapIter) unsafe.Pointer diff --git a/vendor/github.com/goccy/go-json/internal/encoder/opcode.go b/vendor/github.com/goccy/go-json/internal/encoder/opcode.go new file mode 100644 index 000000000..df22f5542 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/opcode.go @@ -0,0 +1,752 @@ +package encoder + +import ( + "bytes" + "fmt" + "sort" + "strings" + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +type OpFlags uint16 + +const ( + AnonymousHeadFlags OpFlags = 1 << 0 + AnonymousKeyFlags OpFlags = 1 << 1 + IndirectFlags OpFlags = 1 << 2 + IsTaggedKeyFlags OpFlags = 1 << 3 + NilCheckFlags OpFlags = 1 << 4 + AddrForMarshalerFlags OpFlags = 1 << 5 + IsNextOpPtrTypeFlags OpFlags = 1 << 6 + IsNilableTypeFlags OpFlags = 1 << 7 + MarshalerContextFlags OpFlags = 1 << 8 + NonEmptyInterfaceFlags OpFlags = 1 << 9 +) + +type Opcode struct { + Op OpType // operation type + Idx uint32 // offset to access ptr + Next *Opcode // next opcode + End *Opcode // array/slice/struct/map end + NextField *Opcode // next struct field + Key string // struct field key + Offset uint32 // offset size from struct header + PtrNum uint8 // pointer number: e.g. double pointer is 2. + NumBitSize uint8 + Flags OpFlags + + Type *runtime.Type // go type + Jmp *CompiledCode // for recursive call + FieldQuery *FieldQuery // field query for Interface / MarshalJSON / MarshalText + ElemIdx uint32 // offset to access array/slice elem + Length uint32 // offset to access slice length or array length + Indent uint32 // indent number + Size uint32 // array/slice elem size + DisplayIdx uint32 // opcode index + DisplayKey string // key text to display +} + +func (c *Opcode) Validate() error { + var prevIdx uint32 + for code := c; !code.IsEnd(); { + if prevIdx != 0 { + if code.DisplayIdx != prevIdx+1 { + return fmt.Errorf( + "invalid index. previous display index is %d but next is %d. dump = %s", + prevIdx, code.DisplayIdx, c.Dump(), + ) + } + } + prevIdx = code.DisplayIdx + code = code.IterNext() + } + return nil +} + +func (c *Opcode) IterNext() *Opcode { + if c == nil { + return nil + } + switch c.Op.CodeType() { + case CodeArrayElem, CodeSliceElem, CodeMapKey: + return c.End + default: + return c.Next + } +} + +func (c *Opcode) IsEnd() bool { + if c == nil { + return true + } + return c.Op == OpEnd || c.Op == OpInterfaceEnd || c.Op == OpRecursiveEnd +} + +func (c *Opcode) MaxIdx() uint32 { + max := uint32(0) + for _, value := range []uint32{ + c.Idx, + c.ElemIdx, + c.Length, + c.Size, + } { + if max < value { + max = value + } + } + return max +} + +func (c *Opcode) ToHeaderType(isString bool) OpType { + switch c.Op { + case OpInt: + if isString { + return OpStructHeadIntString + } + return OpStructHeadInt + case OpIntPtr: + if isString { + return OpStructHeadIntPtrString + } + return OpStructHeadIntPtr + case OpUint: + if isString { + return OpStructHeadUintString + } + return OpStructHeadUint + case OpUintPtr: + if isString { + return OpStructHeadUintPtrString + } + return OpStructHeadUintPtr + case OpFloat32: + if isString { + return OpStructHeadFloat32String + } + return OpStructHeadFloat32 + case OpFloat32Ptr: + if isString { + return OpStructHeadFloat32PtrString + } + return OpStructHeadFloat32Ptr + case OpFloat64: + if isString { + return OpStructHeadFloat64String + } + return OpStructHeadFloat64 + case OpFloat64Ptr: + if isString { + return OpStructHeadFloat64PtrString + } + return OpStructHeadFloat64Ptr + case OpString: + if isString { + return OpStructHeadStringString + } + return OpStructHeadString + case OpStringPtr: + if isString { + return OpStructHeadStringPtrString + } + return OpStructHeadStringPtr + case OpNumber: + if isString { + return OpStructHeadNumberString + } + return OpStructHeadNumber + case OpNumberPtr: + if isString { + return OpStructHeadNumberPtrString + } + return OpStructHeadNumberPtr + case OpBool: + if isString { + return OpStructHeadBoolString + } + return OpStructHeadBool + case OpBoolPtr: + if isString { + return OpStructHeadBoolPtrString + } + return OpStructHeadBoolPtr + case OpBytes: + return OpStructHeadBytes + case OpBytesPtr: + return OpStructHeadBytesPtr + case OpMap: + return OpStructHeadMap + case OpMapPtr: + c.Op = OpMap + return OpStructHeadMapPtr + case OpArray: + return OpStructHeadArray + case OpArrayPtr: + c.Op = OpArray + return OpStructHeadArrayPtr + case OpSlice: + return OpStructHeadSlice + case OpSlicePtr: + c.Op = OpSlice + return OpStructHeadSlicePtr + case OpMarshalJSON: + return OpStructHeadMarshalJSON + case OpMarshalJSONPtr: + return OpStructHeadMarshalJSONPtr + case OpMarshalText: + return OpStructHeadMarshalText + case OpMarshalTextPtr: + return OpStructHeadMarshalTextPtr + } + return OpStructHead +} + +func (c *Opcode) ToFieldType(isString bool) OpType { + switch c.Op { + case OpInt: + if isString { + return OpStructFieldIntString + } + return OpStructFieldInt + case OpIntPtr: + if isString { + return OpStructFieldIntPtrString + } + return OpStructFieldIntPtr + case OpUint: + if isString { + return OpStructFieldUintString + } + return OpStructFieldUint + case OpUintPtr: + if isString { + return OpStructFieldUintPtrString + } + return OpStructFieldUintPtr + case OpFloat32: + if isString { + return OpStructFieldFloat32String + } + return OpStructFieldFloat32 + case OpFloat32Ptr: + if isString { + return OpStructFieldFloat32PtrString + } + return OpStructFieldFloat32Ptr + case OpFloat64: + if isString { + return OpStructFieldFloat64String + } + return OpStructFieldFloat64 + case OpFloat64Ptr: + if isString { + return OpStructFieldFloat64PtrString + } + return OpStructFieldFloat64Ptr + case OpString: + if isString { + return OpStructFieldStringString + } + return OpStructFieldString + case OpStringPtr: + if isString { + return OpStructFieldStringPtrString + } + return OpStructFieldStringPtr + case OpNumber: + if isString { + return OpStructFieldNumberString + } + return OpStructFieldNumber + case OpNumberPtr: + if isString { + return OpStructFieldNumberPtrString + } + return OpStructFieldNumberPtr + case OpBool: + if isString { + return OpStructFieldBoolString + } + return OpStructFieldBool + case OpBoolPtr: + if isString { + return OpStructFieldBoolPtrString + } + return OpStructFieldBoolPtr + case OpBytes: + return OpStructFieldBytes + case OpBytesPtr: + return OpStructFieldBytesPtr + case OpMap: + return OpStructFieldMap + case OpMapPtr: + c.Op = OpMap + return OpStructFieldMapPtr + case OpArray: + return OpStructFieldArray + case OpArrayPtr: + c.Op = OpArray + return OpStructFieldArrayPtr + case OpSlice: + return OpStructFieldSlice + case OpSlicePtr: + c.Op = OpSlice + return OpStructFieldSlicePtr + case OpMarshalJSON: + return OpStructFieldMarshalJSON + case OpMarshalJSONPtr: + return OpStructFieldMarshalJSONPtr + case OpMarshalText: + return OpStructFieldMarshalText + case OpMarshalTextPtr: + return OpStructFieldMarshalTextPtr + } + return OpStructField +} + +func newOpCode(ctx *compileContext, typ *runtime.Type, op OpType) *Opcode { + return newOpCodeWithNext(ctx, typ, op, newEndOp(ctx, typ)) +} + +func opcodeOffset(idx int) uint32 { + return uint32(idx) * uintptrSize +} + +func getCodeAddrByIdx(head *Opcode, idx uint32) *Opcode { + addr := uintptr(unsafe.Pointer(head)) + uintptr(idx)*unsafe.Sizeof(Opcode{}) + return *(**Opcode)(unsafe.Pointer(&addr)) +} + +func copyOpcode(code *Opcode) *Opcode { + codeNum := ToEndCode(code).DisplayIdx + 1 + codeSlice := make([]Opcode, codeNum) + head := (*Opcode)((*runtime.SliceHeader)(unsafe.Pointer(&codeSlice)).Data) + ptr := head + c := code + for { + *ptr = Opcode{ + Op: c.Op, + Key: c.Key, + PtrNum: c.PtrNum, + NumBitSize: c.NumBitSize, + Flags: c.Flags, + Idx: c.Idx, + Offset: c.Offset, + Type: c.Type, + FieldQuery: c.FieldQuery, + DisplayIdx: c.DisplayIdx, + DisplayKey: c.DisplayKey, + ElemIdx: c.ElemIdx, + Length: c.Length, + Size: c.Size, + Indent: c.Indent, + Jmp: c.Jmp, + } + if c.End != nil { + ptr.End = getCodeAddrByIdx(head, c.End.DisplayIdx) + } + if c.NextField != nil { + ptr.NextField = getCodeAddrByIdx(head, c.NextField.DisplayIdx) + } + if c.Next != nil { + ptr.Next = getCodeAddrByIdx(head, c.Next.DisplayIdx) + } + if c.IsEnd() { + break + } + ptr = getCodeAddrByIdx(head, c.DisplayIdx+1) + c = c.IterNext() + } + return head +} + +func setTotalLengthToInterfaceOp(code *Opcode) { + for c := code; !c.IsEnd(); { + if c.Op == OpInterface || c.Op == OpInterfacePtr { + c.Length = uint32(code.TotalLength()) + } + c = c.IterNext() + } +} + +func ToEndCode(code *Opcode) *Opcode { + c := code + for !c.IsEnd() { + c = c.IterNext() + } + return c +} + +func copyToInterfaceOpcode(code *Opcode) *Opcode { + copied := copyOpcode(code) + c := copied + c = ToEndCode(c) + c.Idx += uintptrSize + c.ElemIdx = c.Idx + uintptrSize + c.Length = c.Idx + 2*uintptrSize + c.Op = OpInterfaceEnd + return copied +} + +func newOpCodeWithNext(ctx *compileContext, typ *runtime.Type, op OpType, next *Opcode) *Opcode { + return &Opcode{ + Op: op, + Idx: opcodeOffset(ctx.ptrIndex), + Next: next, + Type: typ, + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + } +} + +func newEndOp(ctx *compileContext, typ *runtime.Type) *Opcode { + return newOpCodeWithNext(ctx, typ, OpEnd, nil) +} + +func (c *Opcode) TotalLength() int { + var idx int + code := c + for !code.IsEnd() { + maxIdx := int(code.MaxIdx() / uintptrSize) + if idx < maxIdx { + idx = maxIdx + } + if code.Op == OpRecursiveEnd { + break + } + code = code.IterNext() + } + maxIdx := int(code.MaxIdx() / uintptrSize) + if idx < maxIdx { + idx = maxIdx + } + return idx + 1 +} + +func (c *Opcode) dumpHead(code *Opcode) string { + var length uint32 + if code.Op.CodeType() == CodeArrayHead { + length = code.Length + } else { + length = code.Length / uintptrSize + } + return fmt.Sprintf( + `[%03d]%s%s ([idx:%d][elemIdx:%d][length:%d])`, + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + code.ElemIdx/uintptrSize, + length, + ) +} + +func (c *Opcode) dumpMapHead(code *Opcode) string { + return fmt.Sprintf( + `[%03d]%s%s ([idx:%d])`, + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + ) +} + +func (c *Opcode) dumpMapEnd(code *Opcode) string { + return fmt.Sprintf( + `[%03d]%s%s ([idx:%d])`, + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + ) +} + +func (c *Opcode) dumpElem(code *Opcode) string { + var length uint32 + if code.Op.CodeType() == CodeArrayElem { + length = code.Length + } else { + length = code.Length / uintptrSize + } + return fmt.Sprintf( + `[%03d]%s%s ([idx:%d][elemIdx:%d][length:%d][size:%d])`, + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + code.ElemIdx/uintptrSize, + length, + code.Size, + ) +} + +func (c *Opcode) dumpField(code *Opcode) string { + return fmt.Sprintf( + `[%03d]%s%s ([idx:%d][key:%s][offset:%d])`, + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + code.DisplayKey, + code.Offset, + ) +} + +func (c *Opcode) dumpKey(code *Opcode) string { + return fmt.Sprintf( + `[%03d]%s%s ([idx:%d])`, + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + ) +} + +func (c *Opcode) dumpValue(code *Opcode) string { + return fmt.Sprintf( + `[%03d]%s%s ([idx:%d])`, + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + ) +} + +func (c *Opcode) Dump() string { + codes := []string{} + for code := c; !code.IsEnd(); { + switch code.Op.CodeType() { + case CodeSliceHead: + codes = append(codes, c.dumpHead(code)) + code = code.Next + case CodeMapHead: + codes = append(codes, c.dumpMapHead(code)) + code = code.Next + case CodeArrayElem, CodeSliceElem: + codes = append(codes, c.dumpElem(code)) + code = code.End + case CodeMapKey: + codes = append(codes, c.dumpKey(code)) + code = code.End + case CodeMapValue: + codes = append(codes, c.dumpValue(code)) + code = code.Next + case CodeMapEnd: + codes = append(codes, c.dumpMapEnd(code)) + code = code.Next + case CodeStructField: + codes = append(codes, c.dumpField(code)) + code = code.Next + case CodeStructEnd: + codes = append(codes, c.dumpField(code)) + code = code.Next + default: + codes = append(codes, fmt.Sprintf( + "[%03d]%s%s ([idx:%d])", + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + )) + code = code.Next + } + } + return strings.Join(codes, "\n") +} + +func (c *Opcode) DumpDOT() string { + type edge struct { + from, to *Opcode + label string + weight int + } + var edges []edge + + b := &bytes.Buffer{} + fmt.Fprintf(b, "digraph \"%p\" {\n", c.Type) + fmt.Fprintln(b, "mclimit=1.5;\nrankdir=TD;\nordering=out;\nnode[shape=box];") + for code := c; !code.IsEnd(); { + label := code.Op.String() + fmt.Fprintf(b, "\"%p\" [label=%q];\n", code, label) + if p := code.Next; p != nil { + edges = append(edges, edge{ + from: code, + to: p, + label: "Next", + weight: 10, + }) + } + if p := code.NextField; p != nil { + edges = append(edges, edge{ + from: code, + to: p, + label: "NextField", + weight: 2, + }) + } + if p := code.End; p != nil { + edges = append(edges, edge{ + from: code, + to: p, + label: "End", + weight: 1, + }) + } + if p := code.Jmp; p != nil { + edges = append(edges, edge{ + from: code, + to: p.Code, + label: "Jmp", + weight: 1, + }) + } + + switch code.Op.CodeType() { + case CodeSliceHead: + code = code.Next + case CodeMapHead: + code = code.Next + case CodeArrayElem, CodeSliceElem: + code = code.End + case CodeMapKey: + code = code.End + case CodeMapValue: + code = code.Next + case CodeMapEnd: + code = code.Next + case CodeStructField: + code = code.Next + case CodeStructEnd: + code = code.Next + default: + code = code.Next + } + if code.IsEnd() { + fmt.Fprintf(b, "\"%p\" [label=%q];\n", code, code.Op.String()) + } + } + sort.Slice(edges, func(i, j int) bool { + return edges[i].to.DisplayIdx < edges[j].to.DisplayIdx + }) + for _, e := range edges { + fmt.Fprintf(b, "\"%p\" -> \"%p\" [label=%q][weight=%d];\n", e.from, e.to, e.label, e.weight) + } + fmt.Fprint(b, "}") + return b.String() +} + +func newSliceHeaderCode(ctx *compileContext, typ *runtime.Type) *Opcode { + idx := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + elemIdx := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + length := opcodeOffset(ctx.ptrIndex) + return &Opcode{ + Op: OpSlice, + Type: typ, + Idx: idx, + DisplayIdx: ctx.opcodeIndex, + ElemIdx: elemIdx, + Length: length, + Indent: ctx.indent, + } +} + +func newSliceElemCode(ctx *compileContext, typ *runtime.Type, head *Opcode, size uintptr) *Opcode { + return &Opcode{ + Op: OpSliceElem, + Type: typ, + Idx: head.Idx, + DisplayIdx: ctx.opcodeIndex, + ElemIdx: head.ElemIdx, + Length: head.Length, + Indent: ctx.indent, + Size: uint32(size), + } +} + +func newArrayHeaderCode(ctx *compileContext, typ *runtime.Type, alen int) *Opcode { + idx := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + elemIdx := opcodeOffset(ctx.ptrIndex) + return &Opcode{ + Op: OpArray, + Type: typ, + Idx: idx, + DisplayIdx: ctx.opcodeIndex, + ElemIdx: elemIdx, + Indent: ctx.indent, + Length: uint32(alen), + } +} + +func newArrayElemCode(ctx *compileContext, typ *runtime.Type, head *Opcode, length int, size uintptr) *Opcode { + return &Opcode{ + Op: OpArrayElem, + Type: typ, + Idx: head.Idx, + DisplayIdx: ctx.opcodeIndex, + ElemIdx: head.ElemIdx, + Length: uint32(length), + Indent: ctx.indent, + Size: uint32(size), + } +} + +func newMapHeaderCode(ctx *compileContext, typ *runtime.Type) *Opcode { + idx := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + return &Opcode{ + Op: OpMap, + Type: typ, + Idx: idx, + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + } +} + +func newMapKeyCode(ctx *compileContext, typ *runtime.Type, head *Opcode) *Opcode { + return &Opcode{ + Op: OpMapKey, + Type: typ, + Idx: head.Idx, + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + } +} + +func newMapValueCode(ctx *compileContext, typ *runtime.Type, head *Opcode) *Opcode { + return &Opcode{ + Op: OpMapValue, + Type: typ, + Idx: head.Idx, + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + } +} + +func newMapEndCode(ctx *compileContext, typ *runtime.Type, head *Opcode) *Opcode { + return &Opcode{ + Op: OpMapEnd, + Type: typ, + Idx: head.Idx, + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + Next: newEndOp(ctx, typ), + } +} + +func newRecursiveCode(ctx *compileContext, typ *runtime.Type, jmp *CompiledCode) *Opcode { + return &Opcode{ + Op: OpRecursive, + Type: typ, + Idx: opcodeOffset(ctx.ptrIndex), + Next: newEndOp(ctx, typ), + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + Jmp: jmp, + } +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/option.go b/vendor/github.com/goccy/go-json/internal/encoder/option.go new file mode 100644 index 000000000..12c58e46c --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/option.go @@ -0,0 +1,48 @@ +package encoder + +import ( + "context" + "io" +) + +type OptionFlag uint8 + +const ( + HTMLEscapeOption OptionFlag = 1 << iota + IndentOption + UnorderedMapOption + DebugOption + ColorizeOption + ContextOption + NormalizeUTF8Option + FieldQueryOption +) + +type Option struct { + Flag OptionFlag + ColorScheme *ColorScheme + Context context.Context + DebugOut io.Writer + DebugDOTOut io.WriteCloser +} + +type EncodeFormat struct { + Header string + Footer string +} + +type EncodeFormatScheme struct { + Int EncodeFormat + Uint EncodeFormat + Float EncodeFormat + Bool EncodeFormat + String EncodeFormat + Binary EncodeFormat + ObjectKey EncodeFormat + Null EncodeFormat +} + +type ( + ColorScheme = EncodeFormatScheme + ColorFormat = EncodeFormat +) diff --git a/vendor/github.com/goccy/go-json/internal/encoder/optype.go b/vendor/github.com/goccy/go-json/internal/encoder/optype.go new file mode 100644 index 000000000..5c1241b47 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/optype.go @@ -0,0 +1,932 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package encoder + +import ( + "strings" +) + +type CodeType int + +const ( + CodeOp CodeType = 0 + CodeArrayHead CodeType = 1 + CodeArrayElem CodeType = 2 + CodeSliceHead CodeType = 3 + CodeSliceElem CodeType = 4 + CodeMapHead CodeType = 5 + CodeMapKey CodeType = 6 + CodeMapValue CodeType = 7 + CodeMapEnd CodeType = 8 + CodeRecursive CodeType = 9 + CodeStructField CodeType = 10 + CodeStructEnd CodeType = 11 +) + +var opTypeStrings = [400]string{ + "End", + "Interface", + "Ptr", + "SliceElem", + "SliceEnd", + "ArrayElem", + "ArrayEnd", + "MapKey", + "MapValue", + "MapEnd", + "Recursive", + "RecursivePtr", + "RecursiveEnd", + "InterfaceEnd", + "Int", + "Uint", + "Float32", + "Float64", + "Bool", + "String", + "Bytes", + "Number", + "Array", + "Map", + "Slice", + "Struct", + "MarshalJSON", + "MarshalText", + "IntString", + "UintString", + "Float32String", + "Float64String", + "BoolString", + "StringString", + "NumberString", + "IntPtr", + "UintPtr", + "Float32Ptr", + "Float64Ptr", + "BoolPtr", + "StringPtr", + "BytesPtr", + "NumberPtr", + "ArrayPtr", + "MapPtr", + "SlicePtr", + "MarshalJSONPtr", + "MarshalTextPtr", + "InterfacePtr", + "IntPtrString", + "UintPtrString", + "Float32PtrString", + "Float64PtrString", + "BoolPtrString", + "StringPtrString", + "NumberPtrString", + "StructHeadInt", + "StructHeadOmitEmptyInt", + "StructPtrHeadInt", + "StructPtrHeadOmitEmptyInt", + "StructHeadUint", + "StructHeadOmitEmptyUint", + "StructPtrHeadUint", + "StructPtrHeadOmitEmptyUint", + "StructHeadFloat32", + "StructHeadOmitEmptyFloat32", + "StructPtrHeadFloat32", + "StructPtrHeadOmitEmptyFloat32", + "StructHeadFloat64", + "StructHeadOmitEmptyFloat64", + "StructPtrHeadFloat64", + "StructPtrHeadOmitEmptyFloat64", + "StructHeadBool", + "StructHeadOmitEmptyBool", + "StructPtrHeadBool", + "StructPtrHeadOmitEmptyBool", + "StructHeadString", + "StructHeadOmitEmptyString", + "StructPtrHeadString", + "StructPtrHeadOmitEmptyString", + "StructHeadBytes", + "StructHeadOmitEmptyBytes", + "StructPtrHeadBytes", + "StructPtrHeadOmitEmptyBytes", + "StructHeadNumber", + "StructHeadOmitEmptyNumber", + "StructPtrHeadNumber", + "StructPtrHeadOmitEmptyNumber", + "StructHeadArray", + "StructHeadOmitEmptyArray", + "StructPtrHeadArray", + "StructPtrHeadOmitEmptyArray", + "StructHeadMap", + "StructHeadOmitEmptyMap", + "StructPtrHeadMap", + "StructPtrHeadOmitEmptyMap", + "StructHeadSlice", + "StructHeadOmitEmptySlice", + "StructPtrHeadSlice", + "StructPtrHeadOmitEmptySlice", + "StructHeadStruct", + "StructHeadOmitEmptyStruct", + "StructPtrHeadStruct", + "StructPtrHeadOmitEmptyStruct", + "StructHeadMarshalJSON", + "StructHeadOmitEmptyMarshalJSON", + "StructPtrHeadMarshalJSON", + "StructPtrHeadOmitEmptyMarshalJSON", + "StructHeadMarshalText", + "StructHeadOmitEmptyMarshalText", + "StructPtrHeadMarshalText", + "StructPtrHeadOmitEmptyMarshalText", + "StructHeadIntString", + "StructHeadOmitEmptyIntString", + "StructPtrHeadIntString", + "StructPtrHeadOmitEmptyIntString", + "StructHeadUintString", + "StructHeadOmitEmptyUintString", + "StructPtrHeadUintString", + "StructPtrHeadOmitEmptyUintString", + "StructHeadFloat32String", + "StructHeadOmitEmptyFloat32String", + "StructPtrHeadFloat32String", + "StructPtrHeadOmitEmptyFloat32String", + "StructHeadFloat64String", + "StructHeadOmitEmptyFloat64String", + "StructPtrHeadFloat64String", + "StructPtrHeadOmitEmptyFloat64String", + "StructHeadBoolString", + "StructHeadOmitEmptyBoolString", + "StructPtrHeadBoolString", + "StructPtrHeadOmitEmptyBoolString", + "StructHeadStringString", + "StructHeadOmitEmptyStringString", + "StructPtrHeadStringString", + "StructPtrHeadOmitEmptyStringString", + "StructHeadNumberString", + "StructHeadOmitEmptyNumberString", + "StructPtrHeadNumberString", + "StructPtrHeadOmitEmptyNumberString", + "StructHeadIntPtr", + "StructHeadOmitEmptyIntPtr", + "StructPtrHeadIntPtr", + "StructPtrHeadOmitEmptyIntPtr", + "StructHeadUintPtr", + "StructHeadOmitEmptyUintPtr", + "StructPtrHeadUintPtr", + "StructPtrHeadOmitEmptyUintPtr", + "StructHeadFloat32Ptr", + "StructHeadOmitEmptyFloat32Ptr", + "StructPtrHeadFloat32Ptr", + "StructPtrHeadOmitEmptyFloat32Ptr", + "StructHeadFloat64Ptr", + "StructHeadOmitEmptyFloat64Ptr", + "StructPtrHeadFloat64Ptr", + "StructPtrHeadOmitEmptyFloat64Ptr", + "StructHeadBoolPtr", + "StructHeadOmitEmptyBoolPtr", + "StructPtrHeadBoolPtr", + "StructPtrHeadOmitEmptyBoolPtr", + "StructHeadStringPtr", + "StructHeadOmitEmptyStringPtr", + "StructPtrHeadStringPtr", + "StructPtrHeadOmitEmptyStringPtr", + "StructHeadBytesPtr", + "StructHeadOmitEmptyBytesPtr", + "StructPtrHeadBytesPtr", + "StructPtrHeadOmitEmptyBytesPtr", + "StructHeadNumberPtr", + "StructHeadOmitEmptyNumberPtr", + "StructPtrHeadNumberPtr", + "StructPtrHeadOmitEmptyNumberPtr", + "StructHeadArrayPtr", + "StructHeadOmitEmptyArrayPtr", + "StructPtrHeadArrayPtr", + "StructPtrHeadOmitEmptyArrayPtr", + "StructHeadMapPtr", + "StructHeadOmitEmptyMapPtr", + "StructPtrHeadMapPtr", + "StructPtrHeadOmitEmptyMapPtr", + "StructHeadSlicePtr", + "StructHeadOmitEmptySlicePtr", + "StructPtrHeadSlicePtr", + "StructPtrHeadOmitEmptySlicePtr", + "StructHeadMarshalJSONPtr", + "StructHeadOmitEmptyMarshalJSONPtr", + "StructPtrHeadMarshalJSONPtr", + "StructPtrHeadOmitEmptyMarshalJSONPtr", + "StructHeadMarshalTextPtr", + "StructHeadOmitEmptyMarshalTextPtr", + "StructPtrHeadMarshalTextPtr", + "StructPtrHeadOmitEmptyMarshalTextPtr", + "StructHeadInterfacePtr", + "StructHeadOmitEmptyInterfacePtr", + "StructPtrHeadInterfacePtr", + "StructPtrHeadOmitEmptyInterfacePtr", + "StructHeadIntPtrString", + "StructHeadOmitEmptyIntPtrString", + "StructPtrHeadIntPtrString", + "StructPtrHeadOmitEmptyIntPtrString", + "StructHeadUintPtrString", + "StructHeadOmitEmptyUintPtrString", + "StructPtrHeadUintPtrString", + "StructPtrHeadOmitEmptyUintPtrString", + "StructHeadFloat32PtrString", + "StructHeadOmitEmptyFloat32PtrString", + "StructPtrHeadFloat32PtrString", + "StructPtrHeadOmitEmptyFloat32PtrString", + "StructHeadFloat64PtrString", + "StructHeadOmitEmptyFloat64PtrString", + "StructPtrHeadFloat64PtrString", + "StructPtrHeadOmitEmptyFloat64PtrString", + "StructHeadBoolPtrString", + "StructHeadOmitEmptyBoolPtrString", + "StructPtrHeadBoolPtrString", + "StructPtrHeadOmitEmptyBoolPtrString", + "StructHeadStringPtrString", + "StructHeadOmitEmptyStringPtrString", + "StructPtrHeadStringPtrString", + "StructPtrHeadOmitEmptyStringPtrString", + "StructHeadNumberPtrString", + "StructHeadOmitEmptyNumberPtrString", + "StructPtrHeadNumberPtrString", + "StructPtrHeadOmitEmptyNumberPtrString", + "StructHead", + "StructHeadOmitEmpty", + "StructPtrHead", + "StructPtrHeadOmitEmpty", + "StructFieldInt", + "StructFieldOmitEmptyInt", + "StructEndInt", + "StructEndOmitEmptyInt", + "StructFieldUint", + "StructFieldOmitEmptyUint", + "StructEndUint", + "StructEndOmitEmptyUint", + "StructFieldFloat32", + "StructFieldOmitEmptyFloat32", + "StructEndFloat32", + "StructEndOmitEmptyFloat32", + "StructFieldFloat64", + "StructFieldOmitEmptyFloat64", + "StructEndFloat64", + "StructEndOmitEmptyFloat64", + "StructFieldBool", + "StructFieldOmitEmptyBool", + "StructEndBool", + "StructEndOmitEmptyBool", + "StructFieldString", + "StructFieldOmitEmptyString", + "StructEndString", + "StructEndOmitEmptyString", + "StructFieldBytes", + "StructFieldOmitEmptyBytes", + "StructEndBytes", + "StructEndOmitEmptyBytes", + "StructFieldNumber", + "StructFieldOmitEmptyNumber", + "StructEndNumber", + "StructEndOmitEmptyNumber", + "StructFieldArray", + "StructFieldOmitEmptyArray", + "StructEndArray", + "StructEndOmitEmptyArray", + "StructFieldMap", + "StructFieldOmitEmptyMap", + "StructEndMap", + "StructEndOmitEmptyMap", + "StructFieldSlice", + "StructFieldOmitEmptySlice", + "StructEndSlice", + "StructEndOmitEmptySlice", + "StructFieldStruct", + "StructFieldOmitEmptyStruct", + "StructEndStruct", + "StructEndOmitEmptyStruct", + "StructFieldMarshalJSON", + "StructFieldOmitEmptyMarshalJSON", + "StructEndMarshalJSON", + "StructEndOmitEmptyMarshalJSON", + "StructFieldMarshalText", + "StructFieldOmitEmptyMarshalText", + "StructEndMarshalText", + "StructEndOmitEmptyMarshalText", + "StructFieldIntString", + "StructFieldOmitEmptyIntString", + "StructEndIntString", + "StructEndOmitEmptyIntString", + "StructFieldUintString", + "StructFieldOmitEmptyUintString", + "StructEndUintString", + "StructEndOmitEmptyUintString", + "StructFieldFloat32String", + "StructFieldOmitEmptyFloat32String", + "StructEndFloat32String", + "StructEndOmitEmptyFloat32String", + "StructFieldFloat64String", + "StructFieldOmitEmptyFloat64String", + "StructEndFloat64String", + "StructEndOmitEmptyFloat64String", + "StructFieldBoolString", + "StructFieldOmitEmptyBoolString", + "StructEndBoolString", + "StructEndOmitEmptyBoolString", + "StructFieldStringString", + "StructFieldOmitEmptyStringString", + "StructEndStringString", + "StructEndOmitEmptyStringString", + "StructFieldNumberString", + "StructFieldOmitEmptyNumberString", + "StructEndNumberString", + "StructEndOmitEmptyNumberString", + "StructFieldIntPtr", + "StructFieldOmitEmptyIntPtr", + "StructEndIntPtr", + "StructEndOmitEmptyIntPtr", + "StructFieldUintPtr", + "StructFieldOmitEmptyUintPtr", + "StructEndUintPtr", + "StructEndOmitEmptyUintPtr", + "StructFieldFloat32Ptr", + "StructFieldOmitEmptyFloat32Ptr", + "StructEndFloat32Ptr", + "StructEndOmitEmptyFloat32Ptr", + "StructFieldFloat64Ptr", + "StructFieldOmitEmptyFloat64Ptr", + "StructEndFloat64Ptr", + "StructEndOmitEmptyFloat64Ptr", + "StructFieldBoolPtr", + "StructFieldOmitEmptyBoolPtr", + "StructEndBoolPtr", + "StructEndOmitEmptyBoolPtr", + "StructFieldStringPtr", + "StructFieldOmitEmptyStringPtr", + "StructEndStringPtr", + "StructEndOmitEmptyStringPtr", + "StructFieldBytesPtr", + "StructFieldOmitEmptyBytesPtr", + "StructEndBytesPtr", + "StructEndOmitEmptyBytesPtr", + "StructFieldNumberPtr", + "StructFieldOmitEmptyNumberPtr", + "StructEndNumberPtr", + "StructEndOmitEmptyNumberPtr", + "StructFieldArrayPtr", + "StructFieldOmitEmptyArrayPtr", + "StructEndArrayPtr", + "StructEndOmitEmptyArrayPtr", + "StructFieldMapPtr", + "StructFieldOmitEmptyMapPtr", + "StructEndMapPtr", + "StructEndOmitEmptyMapPtr", + "StructFieldSlicePtr", + "StructFieldOmitEmptySlicePtr", + "StructEndSlicePtr", + "StructEndOmitEmptySlicePtr", + "StructFieldMarshalJSONPtr", + "StructFieldOmitEmptyMarshalJSONPtr", + "StructEndMarshalJSONPtr", + "StructEndOmitEmptyMarshalJSONPtr", + "StructFieldMarshalTextPtr", + "StructFieldOmitEmptyMarshalTextPtr", + "StructEndMarshalTextPtr", + "StructEndOmitEmptyMarshalTextPtr", + "StructFieldInterfacePtr", + "StructFieldOmitEmptyInterfacePtr", + "StructEndInterfacePtr", + "StructEndOmitEmptyInterfacePtr", + "StructFieldIntPtrString", + "StructFieldOmitEmptyIntPtrString", + "StructEndIntPtrString", + "StructEndOmitEmptyIntPtrString", + "StructFieldUintPtrString", + "StructFieldOmitEmptyUintPtrString", + "StructEndUintPtrString", + "StructEndOmitEmptyUintPtrString", + "StructFieldFloat32PtrString", + "StructFieldOmitEmptyFloat32PtrString", + "StructEndFloat32PtrString", + "StructEndOmitEmptyFloat32PtrString", + "StructFieldFloat64PtrString", + "StructFieldOmitEmptyFloat64PtrString", + "StructEndFloat64PtrString", + "StructEndOmitEmptyFloat64PtrString", + "StructFieldBoolPtrString", + "StructFieldOmitEmptyBoolPtrString", + "StructEndBoolPtrString", + "StructEndOmitEmptyBoolPtrString", + "StructFieldStringPtrString", + "StructFieldOmitEmptyStringPtrString", + "StructEndStringPtrString", + "StructEndOmitEmptyStringPtrString", + "StructFieldNumberPtrString", + "StructFieldOmitEmptyNumberPtrString", + "StructEndNumberPtrString", + "StructEndOmitEmptyNumberPtrString", + "StructField", + "StructFieldOmitEmpty", + "StructEnd", + "StructEndOmitEmpty", +} + +type OpType uint16 + +const ( + OpEnd OpType = 0 + OpInterface OpType = 1 + OpPtr OpType = 2 + OpSliceElem OpType = 3 + OpSliceEnd OpType = 4 + OpArrayElem OpType = 5 + OpArrayEnd OpType = 6 + OpMapKey OpType = 7 + OpMapValue OpType = 8 + OpMapEnd OpType = 9 + OpRecursive OpType = 10 + OpRecursivePtr OpType = 11 + OpRecursiveEnd OpType = 12 + OpInterfaceEnd OpType = 13 + OpInt OpType = 14 + OpUint OpType = 15 + OpFloat32 OpType = 16 + OpFloat64 OpType = 17 + OpBool OpType = 18 + OpString OpType = 19 + OpBytes OpType = 20 + OpNumber OpType = 21 + OpArray OpType = 22 + OpMap OpType = 23 + OpSlice OpType = 24 + OpStruct OpType = 25 + OpMarshalJSON OpType = 26 + OpMarshalText OpType = 27 + OpIntString OpType = 28 + OpUintString OpType = 29 + OpFloat32String OpType = 30 + OpFloat64String OpType = 31 + OpBoolString OpType = 32 + OpStringString OpType = 33 + OpNumberString OpType = 34 + OpIntPtr OpType = 35 + OpUintPtr OpType = 36 + OpFloat32Ptr OpType = 37 + OpFloat64Ptr OpType = 38 + OpBoolPtr OpType = 39 + OpStringPtr OpType = 40 + OpBytesPtr OpType = 41 + OpNumberPtr OpType = 42 + OpArrayPtr OpType = 43 + OpMapPtr OpType = 44 + OpSlicePtr OpType = 45 + OpMarshalJSONPtr OpType = 46 + OpMarshalTextPtr OpType = 47 + OpInterfacePtr OpType = 48 + OpIntPtrString OpType = 49 + OpUintPtrString OpType = 50 + OpFloat32PtrString OpType = 51 + OpFloat64PtrString OpType = 52 + OpBoolPtrString OpType = 53 + OpStringPtrString OpType = 54 + OpNumberPtrString OpType = 55 + OpStructHeadInt OpType = 56 + OpStructHeadOmitEmptyInt OpType = 57 + OpStructPtrHeadInt OpType = 58 + OpStructPtrHeadOmitEmptyInt OpType = 59 + OpStructHeadUint OpType = 60 + OpStructHeadOmitEmptyUint OpType = 61 + OpStructPtrHeadUint OpType = 62 + OpStructPtrHeadOmitEmptyUint OpType = 63 + OpStructHeadFloat32 OpType = 64 + OpStructHeadOmitEmptyFloat32 OpType = 65 + OpStructPtrHeadFloat32 OpType = 66 + OpStructPtrHeadOmitEmptyFloat32 OpType = 67 + OpStructHeadFloat64 OpType = 68 + OpStructHeadOmitEmptyFloat64 OpType = 69 + OpStructPtrHeadFloat64 OpType = 70 + OpStructPtrHeadOmitEmptyFloat64 OpType = 71 + OpStructHeadBool OpType = 72 + OpStructHeadOmitEmptyBool OpType = 73 + OpStructPtrHeadBool OpType = 74 + OpStructPtrHeadOmitEmptyBool OpType = 75 + OpStructHeadString OpType = 76 + OpStructHeadOmitEmptyString OpType = 77 + OpStructPtrHeadString OpType = 78 + OpStructPtrHeadOmitEmptyString OpType = 79 + OpStructHeadBytes OpType = 80 + OpStructHeadOmitEmptyBytes OpType = 81 + OpStructPtrHeadBytes OpType = 82 + OpStructPtrHeadOmitEmptyBytes OpType = 83 + OpStructHeadNumber OpType = 84 + OpStructHeadOmitEmptyNumber OpType = 85 + OpStructPtrHeadNumber OpType = 86 + OpStructPtrHeadOmitEmptyNumber OpType = 87 + OpStructHeadArray OpType = 88 + OpStructHeadOmitEmptyArray OpType = 89 + OpStructPtrHeadArray OpType = 90 + OpStructPtrHeadOmitEmptyArray OpType = 91 + OpStructHeadMap OpType = 92 + OpStructHeadOmitEmptyMap OpType = 93 + OpStructPtrHeadMap OpType = 94 + OpStructPtrHeadOmitEmptyMap OpType = 95 + OpStructHeadSlice OpType = 96 + OpStructHeadOmitEmptySlice OpType = 97 + OpStructPtrHeadSlice OpType = 98 + OpStructPtrHeadOmitEmptySlice OpType = 99 + OpStructHeadStruct OpType = 100 + OpStructHeadOmitEmptyStruct OpType = 101 + OpStructPtrHeadStruct OpType = 102 + OpStructPtrHeadOmitEmptyStruct OpType = 103 + OpStructHeadMarshalJSON OpType = 104 + OpStructHeadOmitEmptyMarshalJSON OpType = 105 + OpStructPtrHeadMarshalJSON OpType = 106 + OpStructPtrHeadOmitEmptyMarshalJSON OpType = 107 + OpStructHeadMarshalText OpType = 108 + OpStructHeadOmitEmptyMarshalText OpType = 109 + OpStructPtrHeadMarshalText OpType = 110 + OpStructPtrHeadOmitEmptyMarshalText OpType = 111 + OpStructHeadIntString OpType = 112 + OpStructHeadOmitEmptyIntString OpType = 113 + OpStructPtrHeadIntString OpType = 114 + OpStructPtrHeadOmitEmptyIntString OpType = 115 + OpStructHeadUintString OpType = 116 + OpStructHeadOmitEmptyUintString OpType = 117 + OpStructPtrHeadUintString OpType = 118 + OpStructPtrHeadOmitEmptyUintString OpType = 119 + OpStructHeadFloat32String OpType = 120 + OpStructHeadOmitEmptyFloat32String OpType = 121 + OpStructPtrHeadFloat32String OpType = 122 + OpStructPtrHeadOmitEmptyFloat32String OpType = 123 + OpStructHeadFloat64String OpType = 124 + OpStructHeadOmitEmptyFloat64String OpType = 125 + OpStructPtrHeadFloat64String OpType = 126 + OpStructPtrHeadOmitEmptyFloat64String OpType = 127 + OpStructHeadBoolString OpType = 128 + OpStructHeadOmitEmptyBoolString OpType = 129 + OpStructPtrHeadBoolString OpType = 130 + OpStructPtrHeadOmitEmptyBoolString OpType = 131 + OpStructHeadStringString OpType = 132 + OpStructHeadOmitEmptyStringString OpType = 133 + OpStructPtrHeadStringString OpType = 134 + OpStructPtrHeadOmitEmptyStringString OpType = 135 + OpStructHeadNumberString OpType = 136 + OpStructHeadOmitEmptyNumberString OpType = 137 + OpStructPtrHeadNumberString OpType = 138 + OpStructPtrHeadOmitEmptyNumberString OpType = 139 + OpStructHeadIntPtr OpType = 140 + OpStructHeadOmitEmptyIntPtr OpType = 141 + OpStructPtrHeadIntPtr OpType = 142 + OpStructPtrHeadOmitEmptyIntPtr OpType = 143 + OpStructHeadUintPtr OpType = 144 + OpStructHeadOmitEmptyUintPtr OpType = 145 + OpStructPtrHeadUintPtr OpType = 146 + OpStructPtrHeadOmitEmptyUintPtr OpType = 147 + OpStructHeadFloat32Ptr OpType = 148 + OpStructHeadOmitEmptyFloat32Ptr OpType = 149 + OpStructPtrHeadFloat32Ptr OpType = 150 + OpStructPtrHeadOmitEmptyFloat32Ptr OpType = 151 + OpStructHeadFloat64Ptr OpType = 152 + OpStructHeadOmitEmptyFloat64Ptr OpType = 153 + OpStructPtrHeadFloat64Ptr OpType = 154 + OpStructPtrHeadOmitEmptyFloat64Ptr OpType = 155 + OpStructHeadBoolPtr OpType = 156 + OpStructHeadOmitEmptyBoolPtr OpType = 157 + OpStructPtrHeadBoolPtr OpType = 158 + OpStructPtrHeadOmitEmptyBoolPtr OpType = 159 + OpStructHeadStringPtr OpType = 160 + OpStructHeadOmitEmptyStringPtr OpType = 161 + OpStructPtrHeadStringPtr OpType = 162 + OpStructPtrHeadOmitEmptyStringPtr OpType = 163 + OpStructHeadBytesPtr OpType = 164 + OpStructHeadOmitEmptyBytesPtr OpType = 165 + OpStructPtrHeadBytesPtr OpType = 166 + OpStructPtrHeadOmitEmptyBytesPtr OpType = 167 + OpStructHeadNumberPtr OpType = 168 + OpStructHeadOmitEmptyNumberPtr OpType = 169 + OpStructPtrHeadNumberPtr OpType = 170 + OpStructPtrHeadOmitEmptyNumberPtr OpType = 171 + OpStructHeadArrayPtr OpType = 172 + OpStructHeadOmitEmptyArrayPtr OpType = 173 + OpStructPtrHeadArrayPtr OpType = 174 + OpStructPtrHeadOmitEmptyArrayPtr OpType = 175 + OpStructHeadMapPtr OpType = 176 + OpStructHeadOmitEmptyMapPtr OpType = 177 + OpStructPtrHeadMapPtr OpType = 178 + OpStructPtrHeadOmitEmptyMapPtr OpType = 179 + OpStructHeadSlicePtr OpType = 180 + OpStructHeadOmitEmptySlicePtr OpType = 181 + OpStructPtrHeadSlicePtr OpType = 182 + OpStructPtrHeadOmitEmptySlicePtr OpType = 183 + OpStructHeadMarshalJSONPtr OpType = 184 + OpStructHeadOmitEmptyMarshalJSONPtr OpType = 185 + OpStructPtrHeadMarshalJSONPtr OpType = 186 + OpStructPtrHeadOmitEmptyMarshalJSONPtr OpType = 187 + OpStructHeadMarshalTextPtr OpType = 188 + OpStructHeadOmitEmptyMarshalTextPtr OpType = 189 + OpStructPtrHeadMarshalTextPtr OpType = 190 + OpStructPtrHeadOmitEmptyMarshalTextPtr OpType = 191 + OpStructHeadInterfacePtr OpType = 192 + OpStructHeadOmitEmptyInterfacePtr OpType = 193 + OpStructPtrHeadInterfacePtr OpType = 194 + OpStructPtrHeadOmitEmptyInterfacePtr OpType = 195 + OpStructHeadIntPtrString OpType = 196 + OpStructHeadOmitEmptyIntPtrString OpType = 197 + OpStructPtrHeadIntPtrString OpType = 198 + OpStructPtrHeadOmitEmptyIntPtrString OpType = 199 + OpStructHeadUintPtrString OpType = 200 + OpStructHeadOmitEmptyUintPtrString OpType = 201 + OpStructPtrHeadUintPtrString OpType = 202 + OpStructPtrHeadOmitEmptyUintPtrString OpType = 203 + OpStructHeadFloat32PtrString OpType = 204 + OpStructHeadOmitEmptyFloat32PtrString OpType = 205 + OpStructPtrHeadFloat32PtrString OpType = 206 + OpStructPtrHeadOmitEmptyFloat32PtrString OpType = 207 + OpStructHeadFloat64PtrString OpType = 208 + OpStructHeadOmitEmptyFloat64PtrString OpType = 209 + OpStructPtrHeadFloat64PtrString OpType = 210 + OpStructPtrHeadOmitEmptyFloat64PtrString OpType = 211 + OpStructHeadBoolPtrString OpType = 212 + OpStructHeadOmitEmptyBoolPtrString OpType = 213 + OpStructPtrHeadBoolPtrString OpType = 214 + OpStructPtrHeadOmitEmptyBoolPtrString OpType = 215 + OpStructHeadStringPtrString OpType = 216 + OpStructHeadOmitEmptyStringPtrString OpType = 217 + OpStructPtrHeadStringPtrString OpType = 218 + OpStructPtrHeadOmitEmptyStringPtrString OpType = 219 + OpStructHeadNumberPtrString OpType = 220 + OpStructHeadOmitEmptyNumberPtrString OpType = 221 + OpStructPtrHeadNumberPtrString OpType = 222 + OpStructPtrHeadOmitEmptyNumberPtrString OpType = 223 + OpStructHead OpType = 224 + OpStructHeadOmitEmpty OpType = 225 + OpStructPtrHead OpType = 226 + OpStructPtrHeadOmitEmpty OpType = 227 + OpStructFieldInt OpType = 228 + OpStructFieldOmitEmptyInt OpType = 229 + OpStructEndInt OpType = 230 + OpStructEndOmitEmptyInt OpType = 231 + OpStructFieldUint OpType = 232 + OpStructFieldOmitEmptyUint OpType = 233 + OpStructEndUint OpType = 234 + OpStructEndOmitEmptyUint OpType = 235 + OpStructFieldFloat32 OpType = 236 + OpStructFieldOmitEmptyFloat32 OpType = 237 + OpStructEndFloat32 OpType = 238 + OpStructEndOmitEmptyFloat32 OpType = 239 + OpStructFieldFloat64 OpType = 240 + OpStructFieldOmitEmptyFloat64 OpType = 241 + OpStructEndFloat64 OpType = 242 + OpStructEndOmitEmptyFloat64 OpType = 243 + OpStructFieldBool OpType = 244 + OpStructFieldOmitEmptyBool OpType = 245 + OpStructEndBool OpType = 246 + OpStructEndOmitEmptyBool OpType = 247 + OpStructFieldString OpType = 248 + OpStructFieldOmitEmptyString OpType = 249 + OpStructEndString OpType = 250 + OpStructEndOmitEmptyString OpType = 251 + OpStructFieldBytes OpType = 252 + OpStructFieldOmitEmptyBytes OpType = 253 + OpStructEndBytes OpType = 254 + OpStructEndOmitEmptyBytes OpType = 255 + OpStructFieldNumber OpType = 256 + OpStructFieldOmitEmptyNumber OpType = 257 + OpStructEndNumber OpType = 258 + OpStructEndOmitEmptyNumber OpType = 259 + OpStructFieldArray OpType = 260 + OpStructFieldOmitEmptyArray OpType = 261 + OpStructEndArray OpType = 262 + OpStructEndOmitEmptyArray OpType = 263 + OpStructFieldMap OpType = 264 + OpStructFieldOmitEmptyMap OpType = 265 + OpStructEndMap OpType = 266 + OpStructEndOmitEmptyMap OpType = 267 + OpStructFieldSlice OpType = 268 + OpStructFieldOmitEmptySlice OpType = 269 + OpStructEndSlice OpType = 270 + OpStructEndOmitEmptySlice OpType = 271 + OpStructFieldStruct OpType = 272 + OpStructFieldOmitEmptyStruct OpType = 273 + OpStructEndStruct OpType = 274 + OpStructEndOmitEmptyStruct OpType = 275 + OpStructFieldMarshalJSON OpType = 276 + OpStructFieldOmitEmptyMarshalJSON OpType = 277 + OpStructEndMarshalJSON OpType = 278 + OpStructEndOmitEmptyMarshalJSON OpType = 279 + OpStructFieldMarshalText OpType = 280 + OpStructFieldOmitEmptyMarshalText OpType = 281 + OpStructEndMarshalText OpType = 282 + OpStructEndOmitEmptyMarshalText OpType = 283 + OpStructFieldIntString OpType = 284 + OpStructFieldOmitEmptyIntString OpType = 285 + OpStructEndIntString OpType = 286 + OpStructEndOmitEmptyIntString OpType = 287 + OpStructFieldUintString OpType = 288 + OpStructFieldOmitEmptyUintString OpType = 289 + OpStructEndUintString OpType = 290 + OpStructEndOmitEmptyUintString OpType = 291 + OpStructFieldFloat32String OpType = 292 + OpStructFieldOmitEmptyFloat32String OpType = 293 + OpStructEndFloat32String OpType = 294 + OpStructEndOmitEmptyFloat32String OpType = 295 + OpStructFieldFloat64String OpType = 296 + OpStructFieldOmitEmptyFloat64String OpType = 297 + OpStructEndFloat64String OpType = 298 + OpStructEndOmitEmptyFloat64String OpType = 299 + OpStructFieldBoolString OpType = 300 + OpStructFieldOmitEmptyBoolString OpType = 301 + OpStructEndBoolString OpType = 302 + OpStructEndOmitEmptyBoolString OpType = 303 + OpStructFieldStringString OpType = 304 + OpStructFieldOmitEmptyStringString OpType = 305 + OpStructEndStringString OpType = 306 + OpStructEndOmitEmptyStringString OpType = 307 + OpStructFieldNumberString OpType = 308 + OpStructFieldOmitEmptyNumberString OpType = 309 + OpStructEndNumberString OpType = 310 + OpStructEndOmitEmptyNumberString OpType = 311 + OpStructFieldIntPtr OpType = 312 + OpStructFieldOmitEmptyIntPtr OpType = 313 + OpStructEndIntPtr OpType = 314 + OpStructEndOmitEmptyIntPtr OpType = 315 + OpStructFieldUintPtr OpType = 316 + OpStructFieldOmitEmptyUintPtr OpType = 317 + OpStructEndUintPtr OpType = 318 + OpStructEndOmitEmptyUintPtr OpType = 319 + OpStructFieldFloat32Ptr OpType = 320 + OpStructFieldOmitEmptyFloat32Ptr OpType = 321 + OpStructEndFloat32Ptr OpType = 322 + OpStructEndOmitEmptyFloat32Ptr OpType = 323 + OpStructFieldFloat64Ptr OpType = 324 + OpStructFieldOmitEmptyFloat64Ptr OpType = 325 + OpStructEndFloat64Ptr OpType = 326 + OpStructEndOmitEmptyFloat64Ptr OpType = 327 + OpStructFieldBoolPtr OpType = 328 + OpStructFieldOmitEmptyBoolPtr OpType = 329 + OpStructEndBoolPtr OpType = 330 + OpStructEndOmitEmptyBoolPtr OpType = 331 + OpStructFieldStringPtr OpType = 332 + OpStructFieldOmitEmptyStringPtr OpType = 333 + OpStructEndStringPtr OpType = 334 + OpStructEndOmitEmptyStringPtr OpType = 335 + OpStructFieldBytesPtr OpType = 336 + OpStructFieldOmitEmptyBytesPtr OpType = 337 + OpStructEndBytesPtr OpType = 338 + OpStructEndOmitEmptyBytesPtr OpType = 339 + OpStructFieldNumberPtr OpType = 340 + OpStructFieldOmitEmptyNumberPtr OpType = 341 + OpStructEndNumberPtr OpType = 342 + OpStructEndOmitEmptyNumberPtr OpType = 343 + OpStructFieldArrayPtr OpType = 344 + OpStructFieldOmitEmptyArrayPtr OpType = 345 + OpStructEndArrayPtr OpType = 346 + OpStructEndOmitEmptyArrayPtr OpType = 347 + OpStructFieldMapPtr OpType = 348 + OpStructFieldOmitEmptyMapPtr OpType = 349 + OpStructEndMapPtr OpType = 350 + OpStructEndOmitEmptyMapPtr OpType = 351 + OpStructFieldSlicePtr OpType = 352 + OpStructFieldOmitEmptySlicePtr OpType = 353 + OpStructEndSlicePtr OpType = 354 + OpStructEndOmitEmptySlicePtr OpType = 355 + OpStructFieldMarshalJSONPtr OpType = 356 + OpStructFieldOmitEmptyMarshalJSONPtr OpType = 357 + OpStructEndMarshalJSONPtr OpType = 358 + OpStructEndOmitEmptyMarshalJSONPtr OpType = 359 + OpStructFieldMarshalTextPtr OpType = 360 + OpStructFieldOmitEmptyMarshalTextPtr OpType = 361 + OpStructEndMarshalTextPtr OpType = 362 + OpStructEndOmitEmptyMarshalTextPtr OpType = 363 + OpStructFieldInterfacePtr OpType = 364 + OpStructFieldOmitEmptyInterfacePtr OpType = 365 + OpStructEndInterfacePtr OpType = 366 + OpStructEndOmitEmptyInterfacePtr OpType = 367 + OpStructFieldIntPtrString OpType = 368 + OpStructFieldOmitEmptyIntPtrString OpType = 369 + OpStructEndIntPtrString OpType = 370 + OpStructEndOmitEmptyIntPtrString OpType = 371 + OpStructFieldUintPtrString OpType = 372 + OpStructFieldOmitEmptyUintPtrString OpType = 373 + OpStructEndUintPtrString OpType = 374 + OpStructEndOmitEmptyUintPtrString OpType = 375 + OpStructFieldFloat32PtrString OpType = 376 + OpStructFieldOmitEmptyFloat32PtrString OpType = 377 + OpStructEndFloat32PtrString OpType = 378 + OpStructEndOmitEmptyFloat32PtrString OpType = 379 + OpStructFieldFloat64PtrString OpType = 380 + OpStructFieldOmitEmptyFloat64PtrString OpType = 381 + OpStructEndFloat64PtrString OpType = 382 + OpStructEndOmitEmptyFloat64PtrString OpType = 383 + OpStructFieldBoolPtrString OpType = 384 + OpStructFieldOmitEmptyBoolPtrString OpType = 385 + OpStructEndBoolPtrString OpType = 386 + OpStructEndOmitEmptyBoolPtrString OpType = 387 + OpStructFieldStringPtrString OpType = 388 + OpStructFieldOmitEmptyStringPtrString OpType = 389 + OpStructEndStringPtrString OpType = 390 + OpStructEndOmitEmptyStringPtrString OpType = 391 + OpStructFieldNumberPtrString OpType = 392 + OpStructFieldOmitEmptyNumberPtrString OpType = 393 + OpStructEndNumberPtrString OpType = 394 + OpStructEndOmitEmptyNumberPtrString OpType = 395 + OpStructField OpType = 396 + OpStructFieldOmitEmpty OpType = 397 + OpStructEnd OpType = 398 + OpStructEndOmitEmpty OpType = 399 +) + +func (t OpType) String() string { + if int(t) >= 400 { + return "" + } + return opTypeStrings[int(t)] +} + +func (t OpType) CodeType() CodeType { + if strings.Contains(t.String(), "Struct") { + if strings.Contains(t.String(), "End") { + return CodeStructEnd + } + return CodeStructField + } + switch t { + case OpArray, OpArrayPtr: + return CodeArrayHead + case OpArrayElem: + return CodeArrayElem + case OpSlice, OpSlicePtr: + return CodeSliceHead + case OpSliceElem: + return CodeSliceElem + case OpMap, OpMapPtr: + return CodeMapHead + case OpMapKey: + return CodeMapKey + case OpMapValue: + return CodeMapValue + case OpMapEnd: + return CodeMapEnd + } + + return CodeOp +} + +func (t OpType) HeadToPtrHead() OpType { + if strings.Index(t.String(), "PtrHead") > 0 { + return t + } + + idx := strings.Index(t.String(), "Head") + if idx == -1 { + return t + } + suffix := "PtrHead" + t.String()[idx+len("Head"):] + + const toPtrOffset = 2 + if strings.Contains(OpType(int(t)+toPtrOffset).String(), suffix) { + return OpType(int(t) + toPtrOffset) + } + return t +} + +func (t OpType) HeadToOmitEmptyHead() OpType { + const toOmitEmptyOffset = 1 + if strings.Contains(OpType(int(t)+toOmitEmptyOffset).String(), "OmitEmpty") { + return OpType(int(t) + toOmitEmptyOffset) + } + + return t +} + +func (t OpType) PtrHeadToHead() OpType { + idx := strings.Index(t.String(), "PtrHead") + if idx == -1 { + return t + } + suffix := t.String()[idx+len("Ptr"):] + + const toPtrOffset = 2 + if strings.Contains(OpType(int(t)-toPtrOffset).String(), suffix) { + return OpType(int(t) - toPtrOffset) + } + return t +} + +func (t OpType) FieldToEnd() OpType { + idx := strings.Index(t.String(), "Field") + if idx == -1 { + return t + } + suffix := t.String()[idx+len("Field"):] + if suffix == "" || suffix == "OmitEmpty" { + return t + } + const toEndOffset = 2 + if strings.Contains(OpType(int(t)+toEndOffset).String(), "End"+suffix) { + return OpType(int(t) + toEndOffset) + } + return t +} + +func (t OpType) FieldToOmitEmptyField() OpType { + const toOmitEmptyOffset = 1 + if strings.Contains(OpType(int(t)+toOmitEmptyOffset).String(), "OmitEmpty") { + return OpType(int(t) + toOmitEmptyOffset) + } + return t +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/query.go b/vendor/github.com/goccy/go-json/internal/encoder/query.go new file mode 100644 index 000000000..1e1850cc1 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/query.go @@ -0,0 +1,135 @@ +package encoder + +import ( + "context" + "fmt" + "reflect" +) + +var ( + Marshal func(interface{}) ([]byte, error) + Unmarshal func([]byte, interface{}) error +) + +type FieldQuery struct { + Name string + Fields []*FieldQuery + hash string +} + +func (q *FieldQuery) Hash() string { + if q.hash != "" { + return q.hash + } + b, _ := Marshal(q) + q.hash = string(b) + return q.hash +} + +func (q *FieldQuery) MarshalJSON() ([]byte, error) { + if q.Name != "" { + if len(q.Fields) > 0 { + return Marshal(map[string][]*FieldQuery{q.Name: q.Fields}) + } + return Marshal(q.Name) + } + return Marshal(q.Fields) +} + +func (q *FieldQuery) QueryString() (FieldQueryString, error) { + b, err := Marshal(q) + if err != nil { + return "", err + } + return FieldQueryString(b), nil +} + +type FieldQueryString string + +func (s FieldQueryString) Build() (*FieldQuery, error) { + var query interface{} + if err := Unmarshal([]byte(s), &query); err != nil { + return nil, err + } + return s.build(reflect.ValueOf(query)) +} + +func (s FieldQueryString) build(v reflect.Value) (*FieldQuery, error) { + switch v.Type().Kind() { + case reflect.String: + return s.buildString(v) + case reflect.Map: + return s.buildMap(v) + case reflect.Slice: + return s.buildSlice(v) + case reflect.Interface: + return s.build(reflect.ValueOf(v.Interface())) + } + return nil, fmt.Errorf("failed to build field query") +} + +func (s FieldQueryString) buildString(v reflect.Value) (*FieldQuery, error) { + b := []byte(v.String()) + switch b[0] { + case '[', '{': + var query interface{} + if err := Unmarshal(b, &query); err != nil { + return nil, err + } + if str, ok := query.(string); ok { + return &FieldQuery{Name: str}, nil + } + return s.build(reflect.ValueOf(query)) + } + return &FieldQuery{Name: string(b)}, nil +} + +func (s FieldQueryString) buildSlice(v reflect.Value) (*FieldQuery, error) { + fields := make([]*FieldQuery, 0, v.Len()) + for i := 0; i < v.Len(); i++ { + def, err := s.build(v.Index(i)) + if err != nil { + return nil, err + } + fields = append(fields, def) + } + return &FieldQuery{Fields: fields}, nil +} + +func (s FieldQueryString) buildMap(v reflect.Value) (*FieldQuery, error) { + keys := v.MapKeys() + if len(keys) != 1 { + return nil, fmt.Errorf("failed to build field query object") + } + key := keys[0] + if key.Type().Kind() != reflect.String { + return nil, fmt.Errorf("failed to build field query. invalid object key type") + } + name := key.String() + def, err := s.build(v.MapIndex(key)) + if err != nil { + return nil, err + } + return &FieldQuery{ + Name: name, + Fields: def.Fields, + }, nil +} + +type queryKey struct{} + +func FieldQueryFromContext(ctx context.Context) *FieldQuery { + query := ctx.Value(queryKey{}) + if query == nil { + return nil + } + q, ok := query.(*FieldQuery) + if !ok { + return nil + } + return q +} + +func SetFieldQueryToContext(ctx context.Context, query *FieldQuery) context.Context { + return context.WithValue(ctx, queryKey{}, query) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/string.go b/vendor/github.com/goccy/go-json/internal/encoder/string.go new file mode 100644 index 000000000..e4152b27c --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/string.go @@ -0,0 +1,459 @@ +package encoder + +import ( + "math/bits" + "reflect" + "unsafe" +) + +const ( + lsb = 0x0101010101010101 + msb = 0x8080808080808080 +) + +var hex = "0123456789abcdef" + +//nolint:govet +func stringToUint64Slice(s string) []uint64 { + return *(*[]uint64)(unsafe.Pointer(&reflect.SliceHeader{ + Data: ((*reflect.StringHeader)(unsafe.Pointer(&s))).Data, + Len: len(s) / 8, + Cap: len(s) / 8, + })) +} + +func AppendString(ctx *RuntimeContext, buf []byte, s string) []byte { + if ctx.Option.Flag&HTMLEscapeOption != 0 { + if ctx.Option.Flag&NormalizeUTF8Option != 0 { + return appendNormalizedHTMLString(buf, s) + } + return appendHTMLString(buf, s) + } + if ctx.Option.Flag&NormalizeUTF8Option != 0 { + return appendNormalizedString(buf, s) + } + return appendString(buf, s) +} + +func appendNormalizedHTMLString(buf []byte, s string) []byte { + valLen := len(s) + if valLen == 0 { + return append(buf, `""`...) + } + buf = append(buf, '"') + var ( + i, j int + ) + if valLen >= 8 { + chunks := stringToUint64Slice(s) + for _, n := range chunks { + // combine masks before checking for the MSB of each byte. We include + // `n` in the mask to check whether any of the *input* byte MSBs were + // set (i.e. the byte was outside the ASCII range). + mask := n | (n - (lsb * 0x20)) | + ((n ^ (lsb * '"')) - lsb) | + ((n ^ (lsb * '\\')) - lsb) | + ((n ^ (lsb * '<')) - lsb) | + ((n ^ (lsb * '>')) - lsb) | + ((n ^ (lsb * '&')) - lsb) + if (mask & msb) != 0 { + j = bits.TrailingZeros64(mask&msb) / 8 + goto ESCAPE_END + } + } + for i := len(chunks) * 8; i < valLen; i++ { + if needEscapeHTMLNormalizeUTF8[s[i]] { + j = i + goto ESCAPE_END + } + } + // no found any escape characters. + return append(append(buf, s...), '"') + } +ESCAPE_END: + for j < valLen { + c := s[j] + + if !needEscapeHTMLNormalizeUTF8[c] { + // fast path: most of the time, printable ascii characters are used + j++ + continue + } + + switch c { + case '\\', '"': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', c) + i = j + 1 + j = j + 1 + continue + + case '\n': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 'n') + i = j + 1 + j = j + 1 + continue + + case '\r': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 'r') + i = j + 1 + j = j + 1 + continue + + case '\t': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 't') + i = j + 1 + j = j + 1 + continue + + case '<', '>', '&': + buf = append(buf, s[i:j]...) + buf = append(buf, `\u00`...) + buf = append(buf, hex[c>>4], hex[c&0xF]) + i = j + 1 + j = j + 1 + continue + + case 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, // 0x00-0x0F + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F: // 0x10-0x1F + buf = append(buf, s[i:j]...) + buf = append(buf, `\u00`...) + buf = append(buf, hex[c>>4], hex[c&0xF]) + i = j + 1 + j = j + 1 + continue + } + state, size := decodeRuneInString(s[j:]) + switch state { + case runeErrorState: + buf = append(buf, s[i:j]...) + buf = append(buf, `\ufffd`...) + i = j + 1 + j = j + 1 + 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. + case lineSepState: + buf = append(buf, s[i:j]...) + buf = append(buf, `\u2028`...) + i = j + 3 + j = j + 3 + continue + case paragraphSepState: + buf = append(buf, s[i:j]...) + buf = append(buf, `\u2029`...) + i = j + 3 + j = j + 3 + continue + } + j += size + } + + return append(append(buf, s[i:]...), '"') +} + +func appendHTMLString(buf []byte, s string) []byte { + valLen := len(s) + if valLen == 0 { + return append(buf, `""`...) + } + buf = append(buf, '"') + var ( + i, j int + ) + if valLen >= 8 { + chunks := stringToUint64Slice(s) + for _, n := range chunks { + // combine masks before checking for the MSB of each byte. We include + // `n` in the mask to check whether any of the *input* byte MSBs were + // set (i.e. the byte was outside the ASCII range). + mask := n | (n - (lsb * 0x20)) | + ((n ^ (lsb * '"')) - lsb) | + ((n ^ (lsb * '\\')) - lsb) | + ((n ^ (lsb * '<')) - lsb) | + ((n ^ (lsb * '>')) - lsb) | + ((n ^ (lsb * '&')) - lsb) + if (mask & msb) != 0 { + j = bits.TrailingZeros64(mask&msb) / 8 + goto ESCAPE_END + } + } + for i := len(chunks) * 8; i < valLen; i++ { + if needEscapeHTML[s[i]] { + j = i + goto ESCAPE_END + } + } + // no found any escape characters. + return append(append(buf, s...), '"') + } +ESCAPE_END: + for j < valLen { + c := s[j] + + if !needEscapeHTML[c] { + // fast path: most of the time, printable ascii characters are used + j++ + continue + } + + switch c { + case '\\', '"': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', c) + i = j + 1 + j = j + 1 + continue + + case '\n': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 'n') + i = j + 1 + j = j + 1 + continue + + case '\r': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 'r') + i = j + 1 + j = j + 1 + continue + + case '\t': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 't') + i = j + 1 + j = j + 1 + continue + + case '<', '>', '&': + buf = append(buf, s[i:j]...) + buf = append(buf, `\u00`...) + buf = append(buf, hex[c>>4], hex[c&0xF]) + i = j + 1 + j = j + 1 + continue + + case 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, // 0x00-0x0F + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F: // 0x10-0x1F + buf = append(buf, s[i:j]...) + buf = append(buf, `\u00`...) + buf = append(buf, hex[c>>4], hex[c&0xF]) + i = j + 1 + j = j + 1 + continue + } + j++ + } + + return append(append(buf, s[i:]...), '"') +} + +func appendNormalizedString(buf []byte, s string) []byte { + valLen := len(s) + if valLen == 0 { + return append(buf, `""`...) + } + buf = append(buf, '"') + var ( + i, j int + ) + if valLen >= 8 { + chunks := stringToUint64Slice(s) + for _, n := range chunks { + // combine masks before checking for the MSB of each byte. We include + // `n` in the mask to check whether any of the *input* byte MSBs were + // set (i.e. the byte was outside the ASCII range). + mask := n | (n - (lsb * 0x20)) | + ((n ^ (lsb * '"')) - lsb) | + ((n ^ (lsb * '\\')) - lsb) + if (mask & msb) != 0 { + j = bits.TrailingZeros64(mask&msb) / 8 + goto ESCAPE_END + } + } + valLen := len(s) + for i := len(chunks) * 8; i < valLen; i++ { + if needEscapeNormalizeUTF8[s[i]] { + j = i + goto ESCAPE_END + } + } + return append(append(buf, s...), '"') + } +ESCAPE_END: + for j < valLen { + c := s[j] + + if !needEscapeNormalizeUTF8[c] { + // fast path: most of the time, printable ascii characters are used + j++ + continue + } + + switch c { + case '\\', '"': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', c) + i = j + 1 + j = j + 1 + continue + + case '\n': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 'n') + i = j + 1 + j = j + 1 + continue + + case '\r': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 'r') + i = j + 1 + j = j + 1 + continue + + case '\t': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 't') + i = j + 1 + j = j + 1 + continue + + case 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, // 0x00-0x0F + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F: // 0x10-0x1F + buf = append(buf, s[i:j]...) + buf = append(buf, `\u00`...) + buf = append(buf, hex[c>>4], hex[c&0xF]) + i = j + 1 + j = j + 1 + continue + } + + state, size := decodeRuneInString(s[j:]) + switch state { + case runeErrorState: + buf = append(buf, s[i:j]...) + buf = append(buf, `\ufffd`...) + i = j + 1 + j = j + 1 + 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. + case lineSepState: + buf = append(buf, s[i:j]...) + buf = append(buf, `\u2028`...) + i = j + 3 + j = j + 3 + continue + case paragraphSepState: + buf = append(buf, s[i:j]...) + buf = append(buf, `\u2029`...) + i = j + 3 + j = j + 3 + continue + } + j += size + } + + return append(append(buf, s[i:]...), '"') +} + +func appendString(buf []byte, s string) []byte { + valLen := len(s) + if valLen == 0 { + return append(buf, `""`...) + } + buf = append(buf, '"') + var ( + i, j int + ) + if valLen >= 8 { + chunks := stringToUint64Slice(s) + for _, n := range chunks { + // combine masks before checking for the MSB of each byte. We include + // `n` in the mask to check whether any of the *input* byte MSBs were + // set (i.e. the byte was outside the ASCII range). + mask := n | (n - (lsb * 0x20)) | + ((n ^ (lsb * '"')) - lsb) | + ((n ^ (lsb * '\\')) - lsb) + if (mask & msb) != 0 { + j = bits.TrailingZeros64(mask&msb) / 8 + goto ESCAPE_END + } + } + valLen := len(s) + for i := len(chunks) * 8; i < valLen; i++ { + if needEscape[s[i]] { + j = i + goto ESCAPE_END + } + } + return append(append(buf, s...), '"') + } +ESCAPE_END: + for j < valLen { + c := s[j] + + if !needEscape[c] { + // fast path: most of the time, printable ascii characters are used + j++ + continue + } + + switch c { + case '\\', '"': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', c) + i = j + 1 + j = j + 1 + continue + + case '\n': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 'n') + i = j + 1 + j = j + 1 + continue + + case '\r': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 'r') + i = j + 1 + j = j + 1 + continue + + case '\t': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 't') + i = j + 1 + j = j + 1 + continue + + case 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, // 0x00-0x0F + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F: // 0x10-0x1F + buf = append(buf, s[i:j]...) + buf = append(buf, `\u00`...) + buf = append(buf, hex[c>>4], hex[c&0xF]) + i = j + 1 + j = j + 1 + continue + } + j++ + } + + return append(append(buf, s[i:]...), '"') +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/string_table.go b/vendor/github.com/goccy/go-json/internal/encoder/string_table.go new file mode 100644 index 000000000..ebe42c92d --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/string_table.go @@ -0,0 +1,415 @@ +package encoder + +var needEscapeHTMLNormalizeUTF8 = [256]bool{ + '"': true, + '&': true, + '<': true, + '>': true, + '\\': true, + 0x00: true, + 0x01: true, + 0x02: true, + 0x03: true, + 0x04: true, + 0x05: true, + 0x06: true, + 0x07: true, + 0x08: true, + 0x09: true, + 0x0a: true, + 0x0b: true, + 0x0c: true, + 0x0d: true, + 0x0e: true, + 0x0f: true, + 0x10: true, + 0x11: true, + 0x12: true, + 0x13: true, + 0x14: true, + 0x15: true, + 0x16: true, + 0x17: true, + 0x18: true, + 0x19: true, + 0x1a: true, + 0x1b: true, + 0x1c: true, + 0x1d: true, + 0x1e: true, + 0x1f: true, + /* 0x20 - 0x7f */ + 0x80: true, + 0x81: true, + 0x82: true, + 0x83: true, + 0x84: true, + 0x85: true, + 0x86: true, + 0x87: true, + 0x88: true, + 0x89: true, + 0x8a: true, + 0x8b: true, + 0x8c: true, + 0x8d: true, + 0x8e: true, + 0x8f: true, + 0x90: true, + 0x91: true, + 0x92: true, + 0x93: true, + 0x94: true, + 0x95: true, + 0x96: true, + 0x97: true, + 0x98: true, + 0x99: true, + 0x9a: true, + 0x9b: true, + 0x9c: true, + 0x9d: true, + 0x9e: true, + 0x9f: true, + 0xa0: true, + 0xa1: true, + 0xa2: true, + 0xa3: true, + 0xa4: true, + 0xa5: true, + 0xa6: true, + 0xa7: true, + 0xa8: true, + 0xa9: true, + 0xaa: true, + 0xab: true, + 0xac: true, + 0xad: true, + 0xae: true, + 0xaf: true, + 0xb0: true, + 0xb1: true, + 0xb2: true, + 0xb3: true, + 0xb4: true, + 0xb5: true, + 0xb6: true, + 0xb7: true, + 0xb8: true, + 0xb9: true, + 0xba: true, + 0xbb: true, + 0xbc: true, + 0xbd: true, + 0xbe: true, + 0xbf: true, + 0xc0: true, + 0xc1: true, + 0xc2: true, + 0xc3: true, + 0xc4: true, + 0xc5: true, + 0xc6: true, + 0xc7: true, + 0xc8: true, + 0xc9: true, + 0xca: true, + 0xcb: true, + 0xcc: true, + 0xcd: true, + 0xce: true, + 0xcf: true, + 0xd0: true, + 0xd1: true, + 0xd2: true, + 0xd3: true, + 0xd4: true, + 0xd5: true, + 0xd6: true, + 0xd7: true, + 0xd8: true, + 0xd9: true, + 0xda: true, + 0xdb: true, + 0xdc: true, + 0xdd: true, + 0xde: true, + 0xdf: true, + 0xe0: true, + 0xe1: true, + 0xe2: true, + 0xe3: true, + 0xe4: true, + 0xe5: true, + 0xe6: true, + 0xe7: true, + 0xe8: true, + 0xe9: true, + 0xea: true, + 0xeb: true, + 0xec: true, + 0xed: true, + 0xee: true, + 0xef: true, + 0xf0: true, + 0xf1: true, + 0xf2: true, + 0xf3: true, + 0xf4: true, + 0xf5: true, + 0xf6: true, + 0xf7: true, + 0xf8: true, + 0xf9: true, + 0xfa: true, + 0xfb: true, + 0xfc: true, + 0xfd: true, + 0xfe: true, + 0xff: true, +} + +var needEscapeNormalizeUTF8 = [256]bool{ + '"': true, + '\\': true, + 0x00: true, + 0x01: true, + 0x02: true, + 0x03: true, + 0x04: true, + 0x05: true, + 0x06: true, + 0x07: true, + 0x08: true, + 0x09: true, + 0x0a: true, + 0x0b: true, + 0x0c: true, + 0x0d: true, + 0x0e: true, + 0x0f: true, + 0x10: true, + 0x11: true, + 0x12: true, + 0x13: true, + 0x14: true, + 0x15: true, + 0x16: true, + 0x17: true, + 0x18: true, + 0x19: true, + 0x1a: true, + 0x1b: true, + 0x1c: true, + 0x1d: true, + 0x1e: true, + 0x1f: true, + /* 0x20 - 0x7f */ + 0x80: true, + 0x81: true, + 0x82: true, + 0x83: true, + 0x84: true, + 0x85: true, + 0x86: true, + 0x87: true, + 0x88: true, + 0x89: true, + 0x8a: true, + 0x8b: true, + 0x8c: true, + 0x8d: true, + 0x8e: true, + 0x8f: true, + 0x90: true, + 0x91: true, + 0x92: true, + 0x93: true, + 0x94: true, + 0x95: true, + 0x96: true, + 0x97: true, + 0x98: true, + 0x99: true, + 0x9a: true, + 0x9b: true, + 0x9c: true, + 0x9d: true, + 0x9e: true, + 0x9f: true, + 0xa0: true, + 0xa1: true, + 0xa2: true, + 0xa3: true, + 0xa4: true, + 0xa5: true, + 0xa6: true, + 0xa7: true, + 0xa8: true, + 0xa9: true, + 0xaa: true, + 0xab: true, + 0xac: true, + 0xad: true, + 0xae: true, + 0xaf: true, + 0xb0: true, + 0xb1: true, + 0xb2: true, + 0xb3: true, + 0xb4: true, + 0xb5: true, + 0xb6: true, + 0xb7: true, + 0xb8: true, + 0xb9: true, + 0xba: true, + 0xbb: true, + 0xbc: true, + 0xbd: true, + 0xbe: true, + 0xbf: true, + 0xc0: true, + 0xc1: true, + 0xc2: true, + 0xc3: true, + 0xc4: true, + 0xc5: true, + 0xc6: true, + 0xc7: true, + 0xc8: true, + 0xc9: true, + 0xca: true, + 0xcb: true, + 0xcc: true, + 0xcd: true, + 0xce: true, + 0xcf: true, + 0xd0: true, + 0xd1: true, + 0xd2: true, + 0xd3: true, + 0xd4: true, + 0xd5: true, + 0xd6: true, + 0xd7: true, + 0xd8: true, + 0xd9: true, + 0xda: true, + 0xdb: true, + 0xdc: true, + 0xdd: true, + 0xde: true, + 0xdf: true, + 0xe0: true, + 0xe1: true, + 0xe2: true, + 0xe3: true, + 0xe4: true, + 0xe5: true, + 0xe6: true, + 0xe7: true, + 0xe8: true, + 0xe9: true, + 0xea: true, + 0xeb: true, + 0xec: true, + 0xed: true, + 0xee: true, + 0xef: true, + 0xf0: true, + 0xf1: true, + 0xf2: true, + 0xf3: true, + 0xf4: true, + 0xf5: true, + 0xf6: true, + 0xf7: true, + 0xf8: true, + 0xf9: true, + 0xfa: true, + 0xfb: true, + 0xfc: true, + 0xfd: true, + 0xfe: true, + 0xff: true, +} + +var needEscapeHTML = [256]bool{ + '"': true, + '&': true, + '<': true, + '>': true, + '\\': true, + 0x00: true, + 0x01: true, + 0x02: true, + 0x03: true, + 0x04: true, + 0x05: true, + 0x06: true, + 0x07: true, + 0x08: true, + 0x09: true, + 0x0a: true, + 0x0b: true, + 0x0c: true, + 0x0d: true, + 0x0e: true, + 0x0f: true, + 0x10: true, + 0x11: true, + 0x12: true, + 0x13: true, + 0x14: true, + 0x15: true, + 0x16: true, + 0x17: true, + 0x18: true, + 0x19: true, + 0x1a: true, + 0x1b: true, + 0x1c: true, + 0x1d: true, + 0x1e: true, + 0x1f: true, + /* 0x20 - 0xff */ +} + +var needEscape = [256]bool{ + '"': true, + '\\': true, + 0x00: true, + 0x01: true, + 0x02: true, + 0x03: true, + 0x04: true, + 0x05: true, + 0x06: true, + 0x07: true, + 0x08: true, + 0x09: true, + 0x0a: true, + 0x0b: true, + 0x0c: true, + 0x0d: true, + 0x0e: true, + 0x0f: true, + 0x10: true, + 0x11: true, + 0x12: true, + 0x13: true, + 0x14: true, + 0x15: true, + 0x16: true, + 0x17: true, + 0x18: true, + 0x19: true, + 0x1a: true, + 0x1b: true, + 0x1c: true, + 0x1d: true, + 0x1e: true, + 0x1f: true, + /* 0x20 - 0xff */ +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go new file mode 100644 index 000000000..82b6dd47f --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go @@ -0,0 +1,41 @@ +package vm + +import ( + "fmt" + "io" + + "github.com/goccy/go-json/internal/encoder" +) + +func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + defer func() { + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + if wc := ctx.Option.DebugDOTOut; wc != nil { + _, _ = io.WriteString(wc, code.DumpDOT()) + wc.Close() + ctx.Option.DebugDOTOut = nil + } + + if err := recover(); err != nil { + w := ctx.Option.DebugOut + fmt.Fprintln(w, "=============[DEBUG]===============") + fmt.Fprintln(w, "* [TYPE]") + fmt.Fprintln(w, codeSet.Type) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [ALL OPCODE]") + fmt.Fprintln(w, code.Dump()) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [CONTEXT]") + fmt.Fprintf(w, "%+v\n", ctx) + fmt.Fprintln(w, "===================================") + panic(err) + } + }() + + return Run(ctx, b, codeSet) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go new file mode 100644 index 000000000..65252b4a5 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go @@ -0,0 +1,9 @@ +package vm + +import ( + // HACK: compile order + // `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile, + // so forcibly make dependencies and avoid compiling in concurrent. + // dependency order: vm => vm_indent => vm_color => vm_color_indent + _ "github.com/goccy/go-json/internal/encoder/vm_indent" +) diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/util.go new file mode 100644 index 000000000..86291d7bb --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/util.go @@ -0,0 +1,207 @@ +package vm + +import ( + "encoding/json" + "fmt" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +var ( + appendInt = encoder.AppendInt + appendUint = encoder.AppendUint + appendFloat32 = encoder.AppendFloat32 + appendFloat64 = encoder.AppendFloat64 + appendString = encoder.AppendString + appendByteSlice = encoder.AppendByteSlice + appendNumber = encoder.AppendNumber + errUnsupportedValue = encoder.ErrUnsupportedValue + errUnsupportedFloat = encoder.ErrUnsupportedFloat + mapiterinit = encoder.MapIterInit + mapiterkey = encoder.MapIterKey + mapitervalue = encoder.MapIterValue + mapiternext = encoder.MapIterNext + maplen = encoder.MapLen +) + +type emptyInterface struct { + typ *runtime.Type + ptr unsafe.Pointer +} + +type nonEmptyInterface struct { + itab *struct { + ityp *runtime.Type // static interface type + typ *runtime.Type // dynamic concrete type + // unused fields... + } + ptr unsafe.Pointer +} + +func errUnimplementedOp(op encoder.OpType) error { + return fmt.Errorf("encoder: opcode %s has not been implemented", op) +} + +func load(base uintptr, idx uint32) uintptr { + addr := base + uintptr(idx) + return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uint32, p uintptr) { + addr := base + uintptr(idx) + **(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr { + addr := base + uintptr(idx) + p := **(**uintptr)(unsafe.Pointer(&addr)) + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUint64(p uintptr, bitSize uint8) uint64 { + switch bitSize { + case 8: + return (uint64)(**(**uint8)(unsafe.Pointer(&p))) + case 16: + return (uint64)(**(**uint16)(unsafe.Pointer(&p))) + case 32: + return (uint64)(**(**uint32)(unsafe.Pointer(&p))) + case 64: + return **(**uint64)(unsafe.Pointer(&p)) + } + return 0 +} +func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { + return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum uint8) uintptr { + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { + return *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) +} + +func appendBool(_ *encoder.RuntimeContext, b []byte, v bool) []byte { + if v { + return append(b, "true"...) + } + return append(b, "false"...) +} + +func appendNull(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, "null"...) +} + +func appendComma(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, ',') +} + +func appendNullComma(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, "null,"...) +} + +func appendColon(_ *encoder.RuntimeContext, b []byte) []byte { + last := len(b) - 1 + b[last] = ':' + return b +} + +func appendMapKeyValue(_ *encoder.RuntimeContext, _ *encoder.Opcode, b, key, value []byte) []byte { + b = append(b, key...) + b[len(b)-1] = ':' + return append(b, value...) +} + +func appendMapEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + b[len(b)-1] = '}' + b = append(b, ',') + return b +} + +func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + return encoder.AppendMarshalJSON(ctx, code, b, v) +} + +func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + return encoder.AppendMarshalText(ctx, code, b, v) +} + +func appendArrayHead(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + return append(b, '[') +} + +func appendArrayEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + b[last] = ']' + return append(b, ',') +} + +func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '[', ']', ',') +} + +func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{', '}', ',') +} + +func appendObjectEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + b[last] = '}' + return append(b, ',') +} + +func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{') +} + +func appendStructKey(_ *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + return append(b, code.Key...) +} + +func appendStructEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + return append(b, '}', ',') +} + +func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + if b[last] == ',' { + b[last] = '}' + return appendComma(ctx, b) + } + return appendStructEnd(ctx, code, b) +} + +func restoreIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, _ uintptr) {} +func storeIndent(_ uintptr, _ *encoder.Opcode, _ uintptr) {} +func appendMapKeyIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b } +func appendArrayElemIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b } diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go new file mode 100644 index 000000000..645d20f9f --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go @@ -0,0 +1,4859 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package vm + +import ( + "math" + "reflect" + "sort" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + recursiveLevel := 0 + ptrOffset := uintptr(0) + ctxptr := ctx.Ptr() + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + for { + switch code.Op { + default: + return nil, errUnimplementedOp(code.Op) + case encoder.OpPtr: + p := load(ctxptr, code.Idx) + code = code.Next + store(ctxptr, code.Idx, ptrToPtr(p)) + case encoder.OpIntPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInt: + b = appendInt(ctx, b, load(ctxptr, code.Idx), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpUint: + b = appendUint(ctx, b, load(ctxptr, code.Idx), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpIntString: + b = append(b, '"') + b = appendInt(ctx, b, load(ctxptr, code.Idx), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintString: + b = append(b, '"') + b = appendUint(ctx, b, load(ctxptr, code.Idx), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat32Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat32: + b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat64Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat64: + v := ptrToFloat64(load(ctxptr, code.Idx)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStringPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpString: + b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBoolPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBool: + b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBytesPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBytes: + b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpNumberPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpNumber: + bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpInterfacePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInterface: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if p == seen { + return nil, errUnsupportedValue(code, p) + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, p) + var ( + typ *runtime.Type + ifacePtr unsafe.Pointer + ) + up := ptrToUnsafePtr(p) + if code.Flags&encoder.NonEmptyInterfaceFlags != 0 { + iface := (*nonEmptyInterface)(up) + ifacePtr = iface.ptr + if iface.itab != nil { + typ = iface.itab.typ + } + } else { + iface := (*emptyInterface)(up) + ifacePtr = iface.ptr + typ = iface.typ + } + if ifacePtr == nil { + isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ) + if !isDirectedNil { + b = appendNullComma(ctx, b) + code = code.Next + break + } + } + ctx.KeepRefs = append(ctx.KeepRefs, up) + ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ))) + if err != nil { + return nil, err + } + + totalLength := uintptr(code.Length) + 3 + nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3 + + var c *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + c = ifaceCodeSet.InterfaceEscapeKeyCode + } else { + c = ifaceCodeSet.InterfaceNoescapeKeyCode + } + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += totalLength * uintptrSize + oldBaseIndent := ctx.BaseIndent + ctx.BaseIndent += code.Indent + + newLen := offsetNum + totalLength + nextTotalLength + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + end := ifaceCodeSet.EndCode + store(ctxptr, c.Idx, uintptr(ifacePtr)) + store(ctxptr, end.Idx, oldOffset) + store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, end, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpInterfaceEnd: + recursiveLevel-- + + // restore ctxptr + offset := load(ctxptr, code.Idx) + restoreIndent(ctx, code, ctxptr) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + b = append(b, `""`...) + b = appendComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpSlicePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpSlice: + p := load(ctxptr, code.Idx) + slice := ptrToSlice(p) + if p == 0 || slice.Data == nil { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.ElemIdx, 0) + store(ctxptr, code.Length, uintptr(slice.Len)) + store(ctxptr, code.Idx, uintptr(slice.Data)) + if slice.Len > 0 { + b = appendArrayHead(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, uintptr(slice.Data)) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpSliceElem: + idx := load(ctxptr, code.ElemIdx) + length := load(ctxptr, code.Length) + idx++ + if idx < length { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + data := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, data+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpArrayPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpArray: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + if code.Length > 0 { + b = appendArrayHead(ctx, code, b) + store(ctxptr, code.ElemIdx, 0) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpArrayElem: + idx := load(ctxptr, code.ElemIdx) + idx++ + if idx < uintptr(code.Length) { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + p := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, p+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpMapPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpMap: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + uptr := ptrToUnsafePtr(p) + mlen := maplen(uptr) + if mlen <= 0 { + b = appendEmptyObject(ctx, b) + code = code.End.Next + break + } + b = appendStructHead(ctx, b) + unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 + mapCtx := encoder.NewMapContext(mlen, unorderedMap) + mapiterinit(code.Type, uptr, &mapCtx.Iter) + store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx))) + ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) + if unorderedMap { + b = appendMapKeyIndent(ctx, code.Next, b) + } else { + mapCtx.Start = len(b) + mapCtx.First = len(b) + } + key := mapiterkey(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + case encoder.OpMapKey: + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) + idx := mapCtx.Idx + idx++ + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + if idx < mapCtx.Len { + b = appendMapKeyIndent(ctx, code, b) + mapCtx.Idx = int(idx) + key := mapiterkey(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + b = appendObjectEnd(ctx, code, b) + encoder.ReleaseMapContext(mapCtx) + code = code.End.Next + } + } else { + mapCtx.Slice.Items[mapCtx.Idx].Value = b[mapCtx.Start:len(b)] + if idx < mapCtx.Len { + mapCtx.Idx = int(idx) + mapCtx.Start = len(b) + key := mapiterkey(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + code = code.End + } + } + case encoder.OpMapValue: + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + b = appendColon(ctx, b) + } else { + mapCtx.Slice.Items[mapCtx.Idx].Key = b[mapCtx.Start:len(b)] + mapCtx.Start = len(b) + } + value := mapitervalue(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(value)) + mapiternext(&mapCtx.Iter) + code = code.Next + case encoder.OpMapEnd: + // this operation only used by sorted map. + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) + sort.Sort(mapCtx.Slice) + buf := mapCtx.Buf + for _, item := range mapCtx.Slice.Items { + buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value) + } + buf = appendMapEnd(ctx, code, buf) + b = b[:mapCtx.First] + b = append(b, buf...) + mapCtx.Buf = buf + encoder.ReleaseMapContext(mapCtx) + code = code.Next + case encoder.OpRecursivePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpRecursive: + ptr := load(ctxptr, code.Idx) + if ptr != 0 { + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if ptr == seen { + return nil, errUnsupportedValue(code, ptr) + } + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, ptr) + c := code.Jmp.Code + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += code.Jmp.CurLen * uintptrSize + oldBaseIndent := ctx.BaseIndent + indentDiffFromTop := c.Indent - 1 + ctx.BaseIndent += code.Indent - indentDiffFromTop + + newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + store(ctxptr, c.Idx, ptr) + store(ctxptr, c.End.Next.Idx, oldOffset) + store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpRecursiveEnd: + recursiveLevel-- + + // restore ctxptr + restoreIndent(ctx, code, ctxptr) + offset := load(ctxptr, code.Idx) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpStructPtrHead: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHead: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if len(code.Key) > 0 { + if (code.Flags&encoder.IsTaggedKeyFlags) != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { + b = appendStructKey(ctx, code, b) + } + } + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + u64 := ptrToUint64(p, code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset))))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + } + case encoder.OpStructPtrHeadNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructPtrHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadArray, encoder.OpStructHeadSlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyArray: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyArray: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptySlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptySlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNullComma(ctx, b) + code = code.NextField + } else { + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + if maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { + p = ptrToPtr(p) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { + p = ptrToPtr(p) + } + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { + p = ptrToPtr(p) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { + p = ptrToPtr(p) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructField: + if code.Flags&encoder.IsTaggedKeyFlags != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { + b = appendStructKey(ctx, code, b) + } + p := load(ctxptr, code.Idx) + uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmpty: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringString: + p := load(ctxptr, code.Idx) + s := ptrToString(p + uintptr(code.Offset)) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldMarshalJSON: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalJSONPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldMarshalText: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalTextPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldArrayPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArrayPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldSlice: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlice: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldSlicePtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldMap: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMap: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldMapPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldStruct: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyStruct: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructEnd: + b = appendStructEndSkipLast(ctx, code, b) + code = code.Next + case encoder.OpStructEndInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, p, code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, p, code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendStructEnd(ctx, code, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + s := ptrToString(p + uintptr(code.Offset)) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytesPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + code = code.Next + case encoder.OpStructEndOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpEnd: + goto END + } + } +END: + return b, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go new file mode 100644 index 000000000..925f61ed8 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go @@ -0,0 +1,35 @@ +package vm_color + +import ( + "fmt" + + "github.com/goccy/go-json/internal/encoder" +) + +func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + defer func() { + if err := recover(); err != nil { + w := ctx.Option.DebugOut + fmt.Fprintln(w, "=============[DEBUG]===============") + fmt.Fprintln(w, "* [TYPE]") + fmt.Fprintln(w, codeSet.Type) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [ALL OPCODE]") + fmt.Fprintln(w, code.Dump()) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [CONTEXT]") + fmt.Fprintf(w, "%+v\n", ctx) + fmt.Fprintln(w, "===================================") + panic(err) + } + }() + + return Run(ctx, b, codeSet) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go new file mode 100644 index 000000000..12ec56c5b --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go @@ -0,0 +1,9 @@ +package vm_color + +import ( + // HACK: compile order + // `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile, + // so forcibly make dependencies and avoid compiling in concurrent. + // dependency order: vm => vm_indent => vm_color => vm_color_indent + _ "github.com/goccy/go-json/internal/encoder/vm_color_indent" +) diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go new file mode 100644 index 000000000..33f29aee4 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go @@ -0,0 +1,274 @@ +package vm_color + +import ( + "encoding/json" + "fmt" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +var ( + errUnsupportedValue = encoder.ErrUnsupportedValue + errUnsupportedFloat = encoder.ErrUnsupportedFloat + mapiterinit = encoder.MapIterInit + mapiterkey = encoder.MapIterKey + mapitervalue = encoder.MapIterValue + mapiternext = encoder.MapIterNext + maplen = encoder.MapLen +) + +type emptyInterface struct { + typ *runtime.Type + ptr unsafe.Pointer +} + +type nonEmptyInterface struct { + itab *struct { + ityp *runtime.Type // static interface type + typ *runtime.Type // dynamic concrete type + // unused fields... + } + ptr unsafe.Pointer +} + +func errUnimplementedOp(op encoder.OpType) error { + return fmt.Errorf("encoder: opcode %s has not been implemented", op) +} + +func load(base uintptr, idx uint32) uintptr { + addr := base + uintptr(idx) + return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uint32, p uintptr) { + addr := base + uintptr(idx) + **(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr { + addr := base + uintptr(idx) + p := **(**uintptr)(unsafe.Pointer(&addr)) + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUint64(p uintptr, bitSize uint8) uint64 { + switch bitSize { + case 8: + return (uint64)(**(**uint8)(unsafe.Pointer(&p))) + case 16: + return (uint64)(**(**uint16)(unsafe.Pointer(&p))) + case 32: + return (uint64)(**(**uint32)(unsafe.Pointer(&p))) + case 64: + return **(**uint64)(unsafe.Pointer(&p)) + } + return 0 +} +func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { + return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum uint8) uintptr { + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { + return *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) +} + +func appendInt(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte { + format := ctx.Option.ColorScheme.Int + b = append(b, format.Header...) + b = encoder.AppendInt(ctx, b, p, code) + return append(b, format.Footer...) +} + +func appendUint(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte { + format := ctx.Option.ColorScheme.Uint + b = append(b, format.Header...) + b = encoder.AppendUint(ctx, b, p, code) + return append(b, format.Footer...) +} + +func appendFloat32(ctx *encoder.RuntimeContext, b []byte, v float32) []byte { + format := ctx.Option.ColorScheme.Float + b = append(b, format.Header...) + b = encoder.AppendFloat32(ctx, b, v) + return append(b, format.Footer...) +} + +func appendFloat64(ctx *encoder.RuntimeContext, b []byte, v float64) []byte { + format := ctx.Option.ColorScheme.Float + b = append(b, format.Header...) + b = encoder.AppendFloat64(ctx, b, v) + return append(b, format.Footer...) +} + +func appendString(ctx *encoder.RuntimeContext, b []byte, v string) []byte { + format := ctx.Option.ColorScheme.String + b = append(b, format.Header...) + b = encoder.AppendString(ctx, b, v) + return append(b, format.Footer...) +} + +func appendByteSlice(ctx *encoder.RuntimeContext, b []byte, src []byte) []byte { + format := ctx.Option.ColorScheme.Binary + b = append(b, format.Header...) + b = encoder.AppendByteSlice(ctx, b, src) + return append(b, format.Footer...) +} + +func appendNumber(ctx *encoder.RuntimeContext, b []byte, n json.Number) ([]byte, error) { + format := ctx.Option.ColorScheme.Int + b = append(b, format.Header...) + bb, err := encoder.AppendNumber(ctx, b, n) + if err != nil { + return nil, err + } + return append(bb, format.Footer...), nil +} + +func appendBool(ctx *encoder.RuntimeContext, b []byte, v bool) []byte { + format := ctx.Option.ColorScheme.Bool + b = append(b, format.Header...) + if v { + b = append(b, "true"...) + } else { + b = append(b, "false"...) + } + return append(b, format.Footer...) +} + +func appendNull(ctx *encoder.RuntimeContext, b []byte) []byte { + format := ctx.Option.ColorScheme.Null + b = append(b, format.Header...) + b = append(b, "null"...) + return append(b, format.Footer...) +} + +func appendComma(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, ',') +} + +func appendNullComma(ctx *encoder.RuntimeContext, b []byte) []byte { + format := ctx.Option.ColorScheme.Null + b = append(b, format.Header...) + b = append(b, "null"...) + return append(append(b, format.Footer...), ',') +} + +func appendColon(_ *encoder.RuntimeContext, b []byte) []byte { + last := len(b) - 1 + b[last] = ':' + return b +} + +func appendMapKeyValue(_ *encoder.RuntimeContext, _ *encoder.Opcode, b, key, value []byte) []byte { + b = append(b, key[:len(key)-1]...) + b = append(b, ':') + return append(b, value...) +} + +func appendMapEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + b[last] = '}' + b = append(b, ',') + return b +} + +func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + return encoder.AppendMarshalJSON(ctx, code, b, v) +} + +func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + format := ctx.Option.ColorScheme.String + b = append(b, format.Header...) + bb, err := encoder.AppendMarshalText(ctx, code, b, v) + if err != nil { + return nil, err + } + return append(bb, format.Footer...), nil +} + +func appendArrayHead(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + return append(b, '[') +} + +func appendArrayEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + b[last] = ']' + return append(b, ',') +} + +func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '[', ']', ',') +} + +func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{', '}', ',') +} + +func appendObjectEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + b[last] = '}' + return append(b, ',') +} + +func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{') +} + +func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + format := ctx.Option.ColorScheme.ObjectKey + b = append(b, format.Header...) + b = append(b, code.Key[:len(code.Key)-1]...) + b = append(b, format.Footer...) + + return append(b, ':') +} + +func appendStructEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + return append(b, '}', ',') +} + +func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + if b[last] == ',' { + b[last] = '}' + return appendComma(ctx, b) + } + return appendStructEnd(ctx, code, b) +} + +func restoreIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, _ uintptr) {} +func storeIndent(_ uintptr, _ *encoder.Opcode, _ uintptr) {} +func appendMapKeyIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b } +func appendArrayElemIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b } diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go new file mode 100644 index 000000000..a63e83e55 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go @@ -0,0 +1,4859 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package vm_color + +import ( + "math" + "reflect" + "sort" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + recursiveLevel := 0 + ptrOffset := uintptr(0) + ctxptr := ctx.Ptr() + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + for { + switch code.Op { + default: + return nil, errUnimplementedOp(code.Op) + case encoder.OpPtr: + p := load(ctxptr, code.Idx) + code = code.Next + store(ctxptr, code.Idx, ptrToPtr(p)) + case encoder.OpIntPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInt: + b = appendInt(ctx, b, load(ctxptr, code.Idx), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpUint: + b = appendUint(ctx, b, load(ctxptr, code.Idx), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpIntString: + b = append(b, '"') + b = appendInt(ctx, b, load(ctxptr, code.Idx), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintString: + b = append(b, '"') + b = appendUint(ctx, b, load(ctxptr, code.Idx), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat32Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat32: + b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat64Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat64: + v := ptrToFloat64(load(ctxptr, code.Idx)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStringPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpString: + b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBoolPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBool: + b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBytesPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBytes: + b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpNumberPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpNumber: + bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpInterfacePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInterface: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if p == seen { + return nil, errUnsupportedValue(code, p) + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, p) + var ( + typ *runtime.Type + ifacePtr unsafe.Pointer + ) + up := ptrToUnsafePtr(p) + if code.Flags&encoder.NonEmptyInterfaceFlags != 0 { + iface := (*nonEmptyInterface)(up) + ifacePtr = iface.ptr + if iface.itab != nil { + typ = iface.itab.typ + } + } else { + iface := (*emptyInterface)(up) + ifacePtr = iface.ptr + typ = iface.typ + } + if ifacePtr == nil { + isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ) + if !isDirectedNil { + b = appendNullComma(ctx, b) + code = code.Next + break + } + } + ctx.KeepRefs = append(ctx.KeepRefs, up) + ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ))) + if err != nil { + return nil, err + } + + totalLength := uintptr(code.Length) + 3 + nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3 + + var c *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + c = ifaceCodeSet.InterfaceEscapeKeyCode + } else { + c = ifaceCodeSet.InterfaceNoescapeKeyCode + } + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += totalLength * uintptrSize + oldBaseIndent := ctx.BaseIndent + ctx.BaseIndent += code.Indent + + newLen := offsetNum + totalLength + nextTotalLength + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + end := ifaceCodeSet.EndCode + store(ctxptr, c.Idx, uintptr(ifacePtr)) + store(ctxptr, end.Idx, oldOffset) + store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, end, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpInterfaceEnd: + recursiveLevel-- + + // restore ctxptr + offset := load(ctxptr, code.Idx) + restoreIndent(ctx, code, ctxptr) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + b = append(b, `""`...) + b = appendComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpSlicePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpSlice: + p := load(ctxptr, code.Idx) + slice := ptrToSlice(p) + if p == 0 || slice.Data == nil { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.ElemIdx, 0) + store(ctxptr, code.Length, uintptr(slice.Len)) + store(ctxptr, code.Idx, uintptr(slice.Data)) + if slice.Len > 0 { + b = appendArrayHead(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, uintptr(slice.Data)) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpSliceElem: + idx := load(ctxptr, code.ElemIdx) + length := load(ctxptr, code.Length) + idx++ + if idx < length { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + data := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, data+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpArrayPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpArray: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + if code.Length > 0 { + b = appendArrayHead(ctx, code, b) + store(ctxptr, code.ElemIdx, 0) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpArrayElem: + idx := load(ctxptr, code.ElemIdx) + idx++ + if idx < uintptr(code.Length) { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + p := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, p+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpMapPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpMap: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + uptr := ptrToUnsafePtr(p) + mlen := maplen(uptr) + if mlen <= 0 { + b = appendEmptyObject(ctx, b) + code = code.End.Next + break + } + b = appendStructHead(ctx, b) + unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 + mapCtx := encoder.NewMapContext(mlen, unorderedMap) + mapiterinit(code.Type, uptr, &mapCtx.Iter) + store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx))) + ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) + if unorderedMap { + b = appendMapKeyIndent(ctx, code.Next, b) + } else { + mapCtx.Start = len(b) + mapCtx.First = len(b) + } + key := mapiterkey(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + case encoder.OpMapKey: + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) + idx := mapCtx.Idx + idx++ + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + if idx < mapCtx.Len { + b = appendMapKeyIndent(ctx, code, b) + mapCtx.Idx = int(idx) + key := mapiterkey(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + b = appendObjectEnd(ctx, code, b) + encoder.ReleaseMapContext(mapCtx) + code = code.End.Next + } + } else { + mapCtx.Slice.Items[mapCtx.Idx].Value = b[mapCtx.Start:len(b)] + if idx < mapCtx.Len { + mapCtx.Idx = int(idx) + mapCtx.Start = len(b) + key := mapiterkey(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + code = code.End + } + } + case encoder.OpMapValue: + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + b = appendColon(ctx, b) + } else { + mapCtx.Slice.Items[mapCtx.Idx].Key = b[mapCtx.Start:len(b)] + mapCtx.Start = len(b) + } + value := mapitervalue(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(value)) + mapiternext(&mapCtx.Iter) + code = code.Next + case encoder.OpMapEnd: + // this operation only used by sorted map. + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) + sort.Sort(mapCtx.Slice) + buf := mapCtx.Buf + for _, item := range mapCtx.Slice.Items { + buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value) + } + buf = appendMapEnd(ctx, code, buf) + b = b[:mapCtx.First] + b = append(b, buf...) + mapCtx.Buf = buf + encoder.ReleaseMapContext(mapCtx) + code = code.Next + case encoder.OpRecursivePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpRecursive: + ptr := load(ctxptr, code.Idx) + if ptr != 0 { + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if ptr == seen { + return nil, errUnsupportedValue(code, ptr) + } + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, ptr) + c := code.Jmp.Code + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += code.Jmp.CurLen * uintptrSize + oldBaseIndent := ctx.BaseIndent + indentDiffFromTop := c.Indent - 1 + ctx.BaseIndent += code.Indent - indentDiffFromTop + + newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + store(ctxptr, c.Idx, ptr) + store(ctxptr, c.End.Next.Idx, oldOffset) + store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpRecursiveEnd: + recursiveLevel-- + + // restore ctxptr + restoreIndent(ctx, code, ctxptr) + offset := load(ctxptr, code.Idx) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpStructPtrHead: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHead: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if len(code.Key) > 0 { + if (code.Flags&encoder.IsTaggedKeyFlags) != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { + b = appendStructKey(ctx, code, b) + } + } + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + u64 := ptrToUint64(p, code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset))))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + } + case encoder.OpStructPtrHeadNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructPtrHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadArray, encoder.OpStructHeadSlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyArray: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyArray: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptySlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptySlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNullComma(ctx, b) + code = code.NextField + } else { + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + if maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { + p = ptrToPtr(p) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { + p = ptrToPtr(p) + } + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { + p = ptrToPtr(p) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { + p = ptrToPtr(p) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructField: + if code.Flags&encoder.IsTaggedKeyFlags != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { + b = appendStructKey(ctx, code, b) + } + p := load(ctxptr, code.Idx) + uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmpty: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringString: + p := load(ctxptr, code.Idx) + s := ptrToString(p + uintptr(code.Offset)) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldMarshalJSON: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalJSONPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldMarshalText: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalTextPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldArrayPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArrayPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldSlice: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlice: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldSlicePtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldMap: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMap: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldMapPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldStruct: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyStruct: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructEnd: + b = appendStructEndSkipLast(ctx, code, b) + code = code.Next + case encoder.OpStructEndInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, p, code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, p, code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendStructEnd(ctx, code, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + s := ptrToString(p + uintptr(code.Offset)) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytesPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + code = code.Next + case encoder.OpStructEndOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpEnd: + goto END + } + } +END: + return b, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go new file mode 100644 index 000000000..dd4cd489e --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go @@ -0,0 +1,35 @@ +package vm_color_indent + +import ( + "fmt" + + "github.com/goccy/go-json/internal/encoder" +) + +func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + defer func() { + if err := recover(); err != nil { + w := ctx.Option.DebugOut + fmt.Fprintln(w, "=============[DEBUG]===============") + fmt.Fprintln(w, "* [TYPE]") + fmt.Fprintln(w, codeSet.Type) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [ALL OPCODE]") + fmt.Fprintln(w, code.Dump()) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [CONTEXT]") + fmt.Fprintf(w, "%+v\n", ctx) + fmt.Fprintln(w, "===================================") + panic(err) + } + }() + + return Run(ctx, b, codeSet) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go new file mode 100644 index 000000000..2395abec9 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go @@ -0,0 +1,297 @@ +package vm_color_indent + +import ( + "encoding/json" + "fmt" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +var ( + appendIndent = encoder.AppendIndent + appendStructEnd = encoder.AppendStructEndIndent + errUnsupportedValue = encoder.ErrUnsupportedValue + errUnsupportedFloat = encoder.ErrUnsupportedFloat + mapiterinit = encoder.MapIterInit + mapiterkey = encoder.MapIterKey + mapitervalue = encoder.MapIterValue + mapiternext = encoder.MapIterNext + maplen = encoder.MapLen +) + +type emptyInterface struct { + typ *runtime.Type + ptr unsafe.Pointer +} + +type nonEmptyInterface struct { + itab *struct { + ityp *runtime.Type // static interface type + typ *runtime.Type // dynamic concrete type + // unused fields... + } + ptr unsafe.Pointer +} + +func errUnimplementedOp(op encoder.OpType) error { + return fmt.Errorf("encoder (indent): opcode %s has not been implemented", op) +} + +func load(base uintptr, idx uint32) uintptr { + addr := base + uintptr(idx) + return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uint32, p uintptr) { + addr := base + uintptr(idx) + **(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr { + addr := base + uintptr(idx) + p := **(**uintptr)(unsafe.Pointer(&addr)) + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUint64(p uintptr, bitSize uint8) uint64 { + switch bitSize { + case 8: + return (uint64)(**(**uint8)(unsafe.Pointer(&p))) + case 16: + return (uint64)(**(**uint16)(unsafe.Pointer(&p))) + case 32: + return (uint64)(**(**uint32)(unsafe.Pointer(&p))) + case 64: + return **(**uint64)(unsafe.Pointer(&p)) + } + return 0 +} + +func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { + return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum uint8) uintptr { + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { + return *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) +} + +func appendInt(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte { + format := ctx.Option.ColorScheme.Int + b = append(b, format.Header...) + b = encoder.AppendInt(ctx, b, p, code) + return append(b, format.Footer...) +} + +func appendUint(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte { + format := ctx.Option.ColorScheme.Uint + b = append(b, format.Header...) + b = encoder.AppendUint(ctx, b, p, code) + return append(b, format.Footer...) +} + +func appendFloat32(ctx *encoder.RuntimeContext, b []byte, v float32) []byte { + format := ctx.Option.ColorScheme.Float + b = append(b, format.Header...) + b = encoder.AppendFloat32(ctx, b, v) + return append(b, format.Footer...) +} + +func appendFloat64(ctx *encoder.RuntimeContext, b []byte, v float64) []byte { + format := ctx.Option.ColorScheme.Float + b = append(b, format.Header...) + b = encoder.AppendFloat64(ctx, b, v) + return append(b, format.Footer...) +} + +func appendString(ctx *encoder.RuntimeContext, b []byte, v string) []byte { + format := ctx.Option.ColorScheme.String + b = append(b, format.Header...) + b = encoder.AppendString(ctx, b, v) + return append(b, format.Footer...) +} + +func appendByteSlice(ctx *encoder.RuntimeContext, b []byte, src []byte) []byte { + format := ctx.Option.ColorScheme.Binary + b = append(b, format.Header...) + b = encoder.AppendByteSlice(ctx, b, src) + return append(b, format.Footer...) +} + +func appendNumber(ctx *encoder.RuntimeContext, b []byte, n json.Number) ([]byte, error) { + format := ctx.Option.ColorScheme.Int + b = append(b, format.Header...) + bb, err := encoder.AppendNumber(ctx, b, n) + if err != nil { + return nil, err + } + return append(bb, format.Footer...), nil +} + +func appendBool(ctx *encoder.RuntimeContext, b []byte, v bool) []byte { + format := ctx.Option.ColorScheme.Bool + b = append(b, format.Header...) + if v { + b = append(b, "true"...) + } else { + b = append(b, "false"...) + } + return append(b, format.Footer...) +} + +func appendNull(ctx *encoder.RuntimeContext, b []byte) []byte { + format := ctx.Option.ColorScheme.Null + b = append(b, format.Header...) + b = append(b, "null"...) + return append(b, format.Footer...) +} + +func appendComma(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, ',', '\n') +} + +func appendNullComma(ctx *encoder.RuntimeContext, b []byte) []byte { + format := ctx.Option.ColorScheme.Null + b = append(b, format.Header...) + b = append(b, "null"...) + return append(append(b, format.Footer...), ',', '\n') +} + +func appendColon(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b[:len(b)-2], ':', ' ') +} + +func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte { + b = appendIndent(ctx, b, code.Indent+1) + b = append(b, key...) + b[len(b)-2] = ':' + b[len(b)-1] = ' ' + return append(b, value...) +} + +func appendMapEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = b[:len(b)-2] + b = append(b, '\n') + b = appendIndent(ctx, b, code.Indent) + return append(b, '}', ',', '\n') +} + +func appendArrayHead(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = append(b, '[', '\n') + return appendIndent(ctx, b, code.Indent+1) +} + +func appendArrayEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = b[:len(b)-2] + b = append(b, '\n') + b = appendIndent(ctx, b, code.Indent) + return append(b, ']', ',', '\n') +} + +func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '[', ']', ',', '\n') +} + +func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{', '}', ',', '\n') +} + +func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + // replace comma to newline + b[last-1] = '\n' + b = appendIndent(ctx, b[:last], code.Indent) + return append(b, '}', ',', '\n') +} + +func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + return encoder.AppendMarshalJSONIndent(ctx, code, b, v) +} + +func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + format := ctx.Option.ColorScheme.String + b = append(b, format.Header...) + bb, err := encoder.AppendMarshalTextIndent(ctx, code, b, v) + if err != nil { + return nil, err + } + return append(bb, format.Footer...), nil +} + +func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{', '\n') +} + +func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = appendIndent(ctx, b, code.Indent) + + format := ctx.Option.ColorScheme.ObjectKey + b = append(b, format.Header...) + b = append(b, code.Key[:len(code.Key)-1]...) + b = append(b, format.Footer...) + + return append(b, ':', ' ') +} + +func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + if b[last-1] == '{' { + b[last] = '}' + } else { + if b[last] == '\n' { + // to remove ',' and '\n' characters + b = b[:len(b)-2] + } + b = append(b, '\n') + b = appendIndent(ctx, b, code.Indent-1) + b = append(b, '}') + } + return appendComma(ctx, b) +} + +func restoreIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, ctxptr uintptr) { + ctx.BaseIndent = uint32(load(ctxptr, code.Length)) +} + +func storeIndent(ctxptr uintptr, code *encoder.Opcode, indent uintptr) { + store(ctxptr, code.Length, indent) +} + +func appendArrayElemIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + return appendIndent(ctx, b, code.Indent+1) +} + +func appendMapKeyIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + return appendIndent(ctx, b, code.Indent) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go new file mode 100644 index 000000000..3b4e22e5d --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go @@ -0,0 +1,4859 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package vm_color_indent + +import ( + "math" + "reflect" + "sort" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + recursiveLevel := 0 + ptrOffset := uintptr(0) + ctxptr := ctx.Ptr() + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + for { + switch code.Op { + default: + return nil, errUnimplementedOp(code.Op) + case encoder.OpPtr: + p := load(ctxptr, code.Idx) + code = code.Next + store(ctxptr, code.Idx, ptrToPtr(p)) + case encoder.OpIntPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInt: + b = appendInt(ctx, b, load(ctxptr, code.Idx), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpUint: + b = appendUint(ctx, b, load(ctxptr, code.Idx), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpIntString: + b = append(b, '"') + b = appendInt(ctx, b, load(ctxptr, code.Idx), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintString: + b = append(b, '"') + b = appendUint(ctx, b, load(ctxptr, code.Idx), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat32Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat32: + b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat64Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat64: + v := ptrToFloat64(load(ctxptr, code.Idx)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStringPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpString: + b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBoolPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBool: + b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBytesPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBytes: + b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpNumberPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpNumber: + bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpInterfacePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInterface: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if p == seen { + return nil, errUnsupportedValue(code, p) + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, p) + var ( + typ *runtime.Type + ifacePtr unsafe.Pointer + ) + up := ptrToUnsafePtr(p) + if code.Flags&encoder.NonEmptyInterfaceFlags != 0 { + iface := (*nonEmptyInterface)(up) + ifacePtr = iface.ptr + if iface.itab != nil { + typ = iface.itab.typ + } + } else { + iface := (*emptyInterface)(up) + ifacePtr = iface.ptr + typ = iface.typ + } + if ifacePtr == nil { + isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ) + if !isDirectedNil { + b = appendNullComma(ctx, b) + code = code.Next + break + } + } + ctx.KeepRefs = append(ctx.KeepRefs, up) + ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ))) + if err != nil { + return nil, err + } + + totalLength := uintptr(code.Length) + 3 + nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3 + + var c *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + c = ifaceCodeSet.InterfaceEscapeKeyCode + } else { + c = ifaceCodeSet.InterfaceNoescapeKeyCode + } + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += totalLength * uintptrSize + oldBaseIndent := ctx.BaseIndent + ctx.BaseIndent += code.Indent + + newLen := offsetNum + totalLength + nextTotalLength + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + end := ifaceCodeSet.EndCode + store(ctxptr, c.Idx, uintptr(ifacePtr)) + store(ctxptr, end.Idx, oldOffset) + store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, end, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpInterfaceEnd: + recursiveLevel-- + + // restore ctxptr + offset := load(ctxptr, code.Idx) + restoreIndent(ctx, code, ctxptr) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + b = append(b, `""`...) + b = appendComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpSlicePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpSlice: + p := load(ctxptr, code.Idx) + slice := ptrToSlice(p) + if p == 0 || slice.Data == nil { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.ElemIdx, 0) + store(ctxptr, code.Length, uintptr(slice.Len)) + store(ctxptr, code.Idx, uintptr(slice.Data)) + if slice.Len > 0 { + b = appendArrayHead(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, uintptr(slice.Data)) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpSliceElem: + idx := load(ctxptr, code.ElemIdx) + length := load(ctxptr, code.Length) + idx++ + if idx < length { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + data := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, data+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpArrayPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpArray: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + if code.Length > 0 { + b = appendArrayHead(ctx, code, b) + store(ctxptr, code.ElemIdx, 0) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpArrayElem: + idx := load(ctxptr, code.ElemIdx) + idx++ + if idx < uintptr(code.Length) { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + p := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, p+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpMapPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpMap: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + uptr := ptrToUnsafePtr(p) + mlen := maplen(uptr) + if mlen <= 0 { + b = appendEmptyObject(ctx, b) + code = code.End.Next + break + } + b = appendStructHead(ctx, b) + unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 + mapCtx := encoder.NewMapContext(mlen, unorderedMap) + mapiterinit(code.Type, uptr, &mapCtx.Iter) + store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx))) + ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) + if unorderedMap { + b = appendMapKeyIndent(ctx, code.Next, b) + } else { + mapCtx.Start = len(b) + mapCtx.First = len(b) + } + key := mapiterkey(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + case encoder.OpMapKey: + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) + idx := mapCtx.Idx + idx++ + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + if idx < mapCtx.Len { + b = appendMapKeyIndent(ctx, code, b) + mapCtx.Idx = int(idx) + key := mapiterkey(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + b = appendObjectEnd(ctx, code, b) + encoder.ReleaseMapContext(mapCtx) + code = code.End.Next + } + } else { + mapCtx.Slice.Items[mapCtx.Idx].Value = b[mapCtx.Start:len(b)] + if idx < mapCtx.Len { + mapCtx.Idx = int(idx) + mapCtx.Start = len(b) + key := mapiterkey(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + code = code.End + } + } + case encoder.OpMapValue: + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + b = appendColon(ctx, b) + } else { + mapCtx.Slice.Items[mapCtx.Idx].Key = b[mapCtx.Start:len(b)] + mapCtx.Start = len(b) + } + value := mapitervalue(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(value)) + mapiternext(&mapCtx.Iter) + code = code.Next + case encoder.OpMapEnd: + // this operation only used by sorted map. + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) + sort.Sort(mapCtx.Slice) + buf := mapCtx.Buf + for _, item := range mapCtx.Slice.Items { + buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value) + } + buf = appendMapEnd(ctx, code, buf) + b = b[:mapCtx.First] + b = append(b, buf...) + mapCtx.Buf = buf + encoder.ReleaseMapContext(mapCtx) + code = code.Next + case encoder.OpRecursivePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpRecursive: + ptr := load(ctxptr, code.Idx) + if ptr != 0 { + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if ptr == seen { + return nil, errUnsupportedValue(code, ptr) + } + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, ptr) + c := code.Jmp.Code + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += code.Jmp.CurLen * uintptrSize + oldBaseIndent := ctx.BaseIndent + indentDiffFromTop := c.Indent - 1 + ctx.BaseIndent += code.Indent - indentDiffFromTop + + newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + store(ctxptr, c.Idx, ptr) + store(ctxptr, c.End.Next.Idx, oldOffset) + store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpRecursiveEnd: + recursiveLevel-- + + // restore ctxptr + restoreIndent(ctx, code, ctxptr) + offset := load(ctxptr, code.Idx) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpStructPtrHead: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHead: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if len(code.Key) > 0 { + if (code.Flags&encoder.IsTaggedKeyFlags) != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { + b = appendStructKey(ctx, code, b) + } + } + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + u64 := ptrToUint64(p, code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset))))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + } + case encoder.OpStructPtrHeadNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructPtrHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadArray, encoder.OpStructHeadSlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyArray: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyArray: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptySlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptySlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNullComma(ctx, b) + code = code.NextField + } else { + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + if maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { + p = ptrToPtr(p) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { + p = ptrToPtr(p) + } + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { + p = ptrToPtr(p) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { + p = ptrToPtr(p) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructField: + if code.Flags&encoder.IsTaggedKeyFlags != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { + b = appendStructKey(ctx, code, b) + } + p := load(ctxptr, code.Idx) + uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmpty: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringString: + p := load(ctxptr, code.Idx) + s := ptrToString(p + uintptr(code.Offset)) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldMarshalJSON: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalJSONPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldMarshalText: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalTextPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldArrayPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArrayPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldSlice: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlice: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldSlicePtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldMap: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMap: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldMapPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldStruct: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyStruct: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructEnd: + b = appendStructEndSkipLast(ctx, code, b) + code = code.Next + case encoder.OpStructEndInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, p, code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, p, code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendStructEnd(ctx, code, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + s := ptrToString(p + uintptr(code.Offset)) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytesPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + code = code.Next + case encoder.OpStructEndOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpEnd: + goto END + } + } +END: + return b, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go new file mode 100644 index 000000000..99395388c --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go @@ -0,0 +1,35 @@ +package vm_indent + +import ( + "fmt" + + "github.com/goccy/go-json/internal/encoder" +) + +func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + defer func() { + if err := recover(); err != nil { + w := ctx.Option.DebugOut + fmt.Fprintln(w, "=============[DEBUG]===============") + fmt.Fprintln(w, "* [TYPE]") + fmt.Fprintln(w, codeSet.Type) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [ALL OPCODE]") + fmt.Fprintln(w, code.Dump()) + fmt.Fprintf(w, "\n") + fmt.Fprintln(w, "* [CONTEXT]") + fmt.Fprintf(w, "%+v\n", ctx) + fmt.Fprintln(w, "===================================") + panic(err) + } + }() + + return Run(ctx, b, codeSet) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go new file mode 100644 index 000000000..9e245bfe5 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go @@ -0,0 +1,9 @@ +package vm_indent + +import ( + // HACK: compile order + // `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile, + // so forcibly make dependencies and avoid compiling in concurrent. + // dependency order: vm => vm_indent => vm_color => vm_color_indent + _ "github.com/goccy/go-json/internal/encoder/vm_color" +) diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go new file mode 100644 index 000000000..6cb745e39 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go @@ -0,0 +1,230 @@ +package vm_indent + +import ( + "encoding/json" + "fmt" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +var ( + appendInt = encoder.AppendInt + appendUint = encoder.AppendUint + appendFloat32 = encoder.AppendFloat32 + appendFloat64 = encoder.AppendFloat64 + appendString = encoder.AppendString + appendByteSlice = encoder.AppendByteSlice + appendNumber = encoder.AppendNumber + appendStructEnd = encoder.AppendStructEndIndent + appendIndent = encoder.AppendIndent + errUnsupportedValue = encoder.ErrUnsupportedValue + errUnsupportedFloat = encoder.ErrUnsupportedFloat + mapiterinit = encoder.MapIterInit + mapiterkey = encoder.MapIterKey + mapitervalue = encoder.MapIterValue + mapiternext = encoder.MapIterNext + maplen = encoder.MapLen +) + +type emptyInterface struct { + typ *runtime.Type + ptr unsafe.Pointer +} + +type nonEmptyInterface struct { + itab *struct { + ityp *runtime.Type // static interface type + typ *runtime.Type // dynamic concrete type + // unused fields... + } + ptr unsafe.Pointer +} + +func errUnimplementedOp(op encoder.OpType) error { + return fmt.Errorf("encoder (indent): opcode %s has not been implemented", op) +} + +func load(base uintptr, idx uint32) uintptr { + addr := base + uintptr(idx) + return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uint32, p uintptr) { + addr := base + uintptr(idx) + **(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr { + addr := base + uintptr(idx) + p := **(**uintptr)(unsafe.Pointer(&addr)) + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUint64(p uintptr, bitSize uint8) uint64 { + switch bitSize { + case 8: + return (uint64)(**(**uint8)(unsafe.Pointer(&p))) + case 16: + return (uint64)(**(**uint16)(unsafe.Pointer(&p))) + case 32: + return (uint64)(**(**uint32)(unsafe.Pointer(&p))) + case 64: + return **(**uint64)(unsafe.Pointer(&p)) + } + return 0 +} +func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { + return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum uint8) uintptr { + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { + return *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) +} + +func appendBool(_ *encoder.RuntimeContext, b []byte, v bool) []byte { + if v { + return append(b, "true"...) + } + return append(b, "false"...) +} + +func appendNull(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, "null"...) +} + +func appendComma(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, ',', '\n') +} + +func appendNullComma(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, "null,\n"...) +} + +func appendColon(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b[:len(b)-2], ':', ' ') +} + +func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte { + b = appendIndent(ctx, b, code.Indent+1) + b = append(b, key...) + b[len(b)-2] = ':' + b[len(b)-1] = ' ' + return append(b, value...) +} + +func appendMapEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = b[:len(b)-2] + b = append(b, '\n') + b = appendIndent(ctx, b, code.Indent) + return append(b, '}', ',', '\n') +} + +func appendArrayHead(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = append(b, '[', '\n') + return appendIndent(ctx, b, code.Indent+1) +} + +func appendArrayEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = b[:len(b)-2] + b = append(b, '\n') + b = appendIndent(ctx, b, code.Indent) + return append(b, ']', ',', '\n') +} + +func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '[', ']', ',', '\n') +} + +func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{', '}', ',', '\n') +} + +func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + // replace comma to newline + b[last-1] = '\n' + b = appendIndent(ctx, b[:last], code.Indent) + return append(b, '}', ',', '\n') +} + +func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + return encoder.AppendMarshalJSONIndent(ctx, code, b, v) +} + +func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + return encoder.AppendMarshalTextIndent(ctx, code, b, v) +} + +func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{', '\n') +} + +func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = appendIndent(ctx, b, code.Indent) + b = append(b, code.Key...) + return append(b, ' ') +} + +func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + if b[last-1] == '{' { + b[last] = '}' + } else { + if b[last] == '\n' { + // to remove ',' and '\n' characters + b = b[:len(b)-2] + } + b = append(b, '\n') + b = appendIndent(ctx, b, code.Indent-1) + b = append(b, '}') + } + return appendComma(ctx, b) +} + +func restoreIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, ctxptr uintptr) { + ctx.BaseIndent = uint32(load(ctxptr, code.Length)) +} + +func storeIndent(ctxptr uintptr, code *encoder.Opcode, indent uintptr) { + store(ctxptr, code.Length, indent) +} + +func appendArrayElemIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + return appendIndent(ctx, b, code.Indent+1) +} + +func appendMapKeyIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + return appendIndent(ctx, b, code.Indent) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go new file mode 100644 index 000000000..836c5c8a8 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go @@ -0,0 +1,4859 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package vm_indent + +import ( + "math" + "reflect" + "sort" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + recursiveLevel := 0 + ptrOffset := uintptr(0) + ctxptr := ctx.Ptr() + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + for { + switch code.Op { + default: + return nil, errUnimplementedOp(code.Op) + case encoder.OpPtr: + p := load(ctxptr, code.Idx) + code = code.Next + store(ctxptr, code.Idx, ptrToPtr(p)) + case encoder.OpIntPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInt: + b = appendInt(ctx, b, load(ctxptr, code.Idx), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpUint: + b = appendUint(ctx, b, load(ctxptr, code.Idx), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpIntString: + b = append(b, '"') + b = appendInt(ctx, b, load(ctxptr, code.Idx), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintString: + b = append(b, '"') + b = appendUint(ctx, b, load(ctxptr, code.Idx), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat32Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat32: + b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat64Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat64: + v := ptrToFloat64(load(ctxptr, code.Idx)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStringPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpString: + b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBoolPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBool: + b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBytesPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBytes: + b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpNumberPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpNumber: + bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpInterfacePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInterface: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if p == seen { + return nil, errUnsupportedValue(code, p) + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, p) + var ( + typ *runtime.Type + ifacePtr unsafe.Pointer + ) + up := ptrToUnsafePtr(p) + if code.Flags&encoder.NonEmptyInterfaceFlags != 0 { + iface := (*nonEmptyInterface)(up) + ifacePtr = iface.ptr + if iface.itab != nil { + typ = iface.itab.typ + } + } else { + iface := (*emptyInterface)(up) + ifacePtr = iface.ptr + typ = iface.typ + } + if ifacePtr == nil { + isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ) + if !isDirectedNil { + b = appendNullComma(ctx, b) + code = code.Next + break + } + } + ctx.KeepRefs = append(ctx.KeepRefs, up) + ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ))) + if err != nil { + return nil, err + } + + totalLength := uintptr(code.Length) + 3 + nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3 + + var c *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + c = ifaceCodeSet.InterfaceEscapeKeyCode + } else { + c = ifaceCodeSet.InterfaceNoescapeKeyCode + } + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += totalLength * uintptrSize + oldBaseIndent := ctx.BaseIndent + ctx.BaseIndent += code.Indent + + newLen := offsetNum + totalLength + nextTotalLength + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + end := ifaceCodeSet.EndCode + store(ctxptr, c.Idx, uintptr(ifacePtr)) + store(ctxptr, end.Idx, oldOffset) + store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, end, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpInterfaceEnd: + recursiveLevel-- + + // restore ctxptr + offset := load(ctxptr, code.Idx) + restoreIndent(ctx, code, ctxptr) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + b = append(b, `""`...) + b = appendComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpSlicePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpSlice: + p := load(ctxptr, code.Idx) + slice := ptrToSlice(p) + if p == 0 || slice.Data == nil { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.ElemIdx, 0) + store(ctxptr, code.Length, uintptr(slice.Len)) + store(ctxptr, code.Idx, uintptr(slice.Data)) + if slice.Len > 0 { + b = appendArrayHead(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, uintptr(slice.Data)) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpSliceElem: + idx := load(ctxptr, code.ElemIdx) + length := load(ctxptr, code.Length) + idx++ + if idx < length { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + data := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, data+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpArrayPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpArray: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + if code.Length > 0 { + b = appendArrayHead(ctx, code, b) + store(ctxptr, code.ElemIdx, 0) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpArrayElem: + idx := load(ctxptr, code.ElemIdx) + idx++ + if idx < uintptr(code.Length) { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + p := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, p+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpMapPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpMap: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.End.Next + break + } + uptr := ptrToUnsafePtr(p) + mlen := maplen(uptr) + if mlen <= 0 { + b = appendEmptyObject(ctx, b) + code = code.End.Next + break + } + b = appendStructHead(ctx, b) + unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 + mapCtx := encoder.NewMapContext(mlen, unorderedMap) + mapiterinit(code.Type, uptr, &mapCtx.Iter) + store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx))) + ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) + if unorderedMap { + b = appendMapKeyIndent(ctx, code.Next, b) + } else { + mapCtx.Start = len(b) + mapCtx.First = len(b) + } + key := mapiterkey(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + case encoder.OpMapKey: + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) + idx := mapCtx.Idx + idx++ + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + if idx < mapCtx.Len { + b = appendMapKeyIndent(ctx, code, b) + mapCtx.Idx = int(idx) + key := mapiterkey(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + b = appendObjectEnd(ctx, code, b) + encoder.ReleaseMapContext(mapCtx) + code = code.End.Next + } + } else { + mapCtx.Slice.Items[mapCtx.Idx].Value = b[mapCtx.Start:len(b)] + if idx < mapCtx.Len { + mapCtx.Idx = int(idx) + mapCtx.Start = len(b) + key := mapiterkey(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + code = code.End + } + } + case encoder.OpMapValue: + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + b = appendColon(ctx, b) + } else { + mapCtx.Slice.Items[mapCtx.Idx].Key = b[mapCtx.Start:len(b)] + mapCtx.Start = len(b) + } + value := mapitervalue(&mapCtx.Iter) + store(ctxptr, code.Next.Idx, uintptr(value)) + mapiternext(&mapCtx.Iter) + code = code.Next + case encoder.OpMapEnd: + // this operation only used by sorted map. + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx))) + sort.Sort(mapCtx.Slice) + buf := mapCtx.Buf + for _, item := range mapCtx.Slice.Items { + buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value) + } + buf = appendMapEnd(ctx, code, buf) + b = b[:mapCtx.First] + b = append(b, buf...) + mapCtx.Buf = buf + encoder.ReleaseMapContext(mapCtx) + code = code.Next + case encoder.OpRecursivePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpRecursive: + ptr := load(ctxptr, code.Idx) + if ptr != 0 { + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if ptr == seen { + return nil, errUnsupportedValue(code, ptr) + } + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, ptr) + c := code.Jmp.Code + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += code.Jmp.CurLen * uintptrSize + oldBaseIndent := ctx.BaseIndent + indentDiffFromTop := c.Indent - 1 + ctx.BaseIndent += code.Indent - indentDiffFromTop + + newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + store(ctxptr, c.Idx, ptr) + store(ctxptr, c.End.Next.Idx, oldOffset) + store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpRecursiveEnd: + recursiveLevel-- + + // restore ctxptr + restoreIndent(ctx, code, ctxptr) + offset := load(ctxptr, code.Idx) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpStructPtrHead: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHead: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if len(code.Key) > 0 { + if (code.Flags&encoder.IsTaggedKeyFlags) != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { + b = appendStructKey(ctx, code, b) + } + } + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + u64 := ptrToUint64(p, code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset))))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + } + case encoder.OpStructPtrHeadNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructPtrHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadArray, encoder.OpStructHeadSlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyArray: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyArray: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptySlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptySlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNullComma(ctx, b) + code = code.NextField + } else { + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + if maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { + p = ptrToPtr(p) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { + p = ptrToPtr(p) + } + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { + p = ptrToPtr(p) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { + p = ptrToPtr(p) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNullComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructField: + if code.Flags&encoder.IsTaggedKeyFlags != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 { + b = appendStructKey(ctx, code, b) + } + p := load(ctxptr, code.Idx) + uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmpty: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, p, code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNullComma(ctx, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringString: + p := load(ctxptr, code.Idx) + s := ptrToString(p + uintptr(code.Offset)) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldMarshalJSON: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalJSONPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldMarshalText: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalTextPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldArrayPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArrayPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldSlice: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlice: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldSlicePtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldMap: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMap: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldMapPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldStruct: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyStruct: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructEnd: + b = appendStructEndSkipLast(ctx, code, b) + code = code.Next + case encoder.OpStructEndInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, p, code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, p, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, p, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p+uintptr(code.Offset), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, p, code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, p, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, p, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendStructEnd(ctx, code, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + s := ptrToString(p + uintptr(code.Offset)) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytesPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + code = code.Next + case encoder.OpStructEndOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpEnd: + goto END + } + } +END: + return b, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/errors/error.go b/vendor/github.com/goccy/go-json/internal/errors/error.go new file mode 100644 index 000000000..9207d0ff2 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/errors/error.go @@ -0,0 +1,183 @@ +package errors + +import ( + "fmt" + "reflect" + "strconv" +) + +type InvalidUTF8Error struct { + S string // the whole string value that caused the error +} + +func (e *InvalidUTF8Error) Error() string { + return fmt.Sprintf("json: invalid UTF-8 in string: %s", strconv.Quote(e.S)) +} + +type InvalidUnmarshalError struct { + Type reflect.Type +} + +func (e *InvalidUnmarshalError) Error() string { + if e.Type == nil { + return "json: Unmarshal(nil)" + } + + if e.Type.Kind() != reflect.Ptr { + return fmt.Sprintf("json: Unmarshal(non-pointer %s)", e.Type) + } + return fmt.Sprintf("json: Unmarshal(nil %s)", e.Type) +} + +// A MarshalerError represents an error from calling a MarshalJSON or MarshalText method. +type MarshalerError struct { + Type reflect.Type + Err error + sourceFunc string +} + +func (e *MarshalerError) Error() string { + srcFunc := e.sourceFunc + if srcFunc == "" { + srcFunc = "MarshalJSON" + } + return fmt.Sprintf("json: error calling %s for type %s: %s", srcFunc, e.Type, e.Err.Error()) +} + +// Unwrap returns the underlying error. +func (e *MarshalerError) Unwrap() error { return e.Err } + +// A SyntaxError is a description of a JSON syntax error. +type SyntaxError struct { + msg string // description of error + Offset int64 // error occurred after reading Offset bytes +} + +func (e *SyntaxError) Error() string { return e.msg } + +// 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 struct { + Key string + Type reflect.Type + Field reflect.StructField +} + +func (e *UnmarshalFieldError) Error() string { + return fmt.Sprintf("json: cannot unmarshal object key %s into unexported field %s of type %s", + strconv.Quote(e.Key), e.Field.Name, e.Type.String(), + ) +} + +// An UnmarshalTypeError describes a JSON value that was +// not appropriate for a value of a specific Go type. +type UnmarshalTypeError struct { + Value string // description of JSON value - "bool", "array", "number -5" + Type reflect.Type // type of Go value it could not be assigned to + Offset int64 // error occurred after reading Offset bytes + Struct string // name of the struct type containing the field + Field string // the full path from root node to the field +} + +func (e *UnmarshalTypeError) Error() string { + if e.Struct != "" || e.Field != "" { + return fmt.Sprintf("json: cannot unmarshal %s into Go struct field %s.%s of type %s", + e.Value, e.Struct, e.Field, e.Type, + ) + } + return fmt.Sprintf("json: cannot unmarshal %s into Go value of type %s", e.Value, e.Type) +} + +// An UnsupportedTypeError is returned by Marshal when attempting +// to encode an unsupported value type. +type UnsupportedTypeError struct { + Type reflect.Type +} + +func (e *UnsupportedTypeError) Error() string { + return fmt.Sprintf("json: unsupported type: %s", e.Type) +} + +type UnsupportedValueError struct { + Value reflect.Value + Str string +} + +func (e *UnsupportedValueError) Error() string { + return fmt.Sprintf("json: unsupported value: %s", e.Str) +} + +func ErrSyntax(msg string, offset int64) *SyntaxError { + return &SyntaxError{msg: msg, Offset: offset} +} + +func ErrMarshaler(typ reflect.Type, err error, msg string) *MarshalerError { + return &MarshalerError{ + Type: typ, + Err: err, + sourceFunc: msg, + } +} + +func ErrExceededMaxDepth(c byte, cursor int64) *SyntaxError { + return &SyntaxError{ + msg: fmt.Sprintf(`invalid character "%c" exceeded max depth`, c), + Offset: cursor, + } +} + +func ErrNotAtBeginningOfValue(cursor int64) *SyntaxError { + return &SyntaxError{msg: "not at beginning of value", Offset: cursor} +} + +func ErrUnexpectedEndOfJSON(msg string, cursor int64) *SyntaxError { + return &SyntaxError{ + msg: fmt.Sprintf("json: %s unexpected end of JSON input", msg), + Offset: cursor, + } +} + +func ErrExpected(msg string, cursor int64) *SyntaxError { + return &SyntaxError{msg: fmt.Sprintf("expected %s", msg), Offset: cursor} +} + +func ErrInvalidCharacter(c byte, context string, cursor int64) *SyntaxError { + if c == 0 { + return &SyntaxError{ + msg: fmt.Sprintf("json: invalid character as %s", context), + Offset: cursor, + } + } + return &SyntaxError{ + msg: fmt.Sprintf("json: invalid character %c as %s", c, context), + Offset: cursor, + } +} + +func ErrInvalidBeginningOfValue(c byte, cursor int64) *SyntaxError { + return &SyntaxError{ + msg: fmt.Sprintf("invalid character '%c' looking for beginning of value", c), + Offset: cursor, + } +} + +type PathError struct { + msg string +} + +func (e *PathError) Error() string { + return fmt.Sprintf("json: invalid path format: %s", e.msg) +} + +func ErrInvalidPath(msg string, args ...interface{}) *PathError { + if len(args) != 0 { + return &PathError{msg: fmt.Sprintf(msg, args...)} + } + return &PathError{msg: msg} +} + +func ErrEmptyPath() *PathError { + return &PathError{msg: "path is empty"} +} diff --git a/vendor/github.com/goccy/go-json/internal/runtime/rtype.go b/vendor/github.com/goccy/go-json/internal/runtime/rtype.go new file mode 100644 index 000000000..4db10debe --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/runtime/rtype.go @@ -0,0 +1,263 @@ +package runtime + +import ( + "reflect" + "unsafe" +) + +// Type representing reflect.rtype for noescape trick +type Type struct{} + +//go:linkname rtype_Align reflect.(*rtype).Align +//go:noescape +func rtype_Align(*Type) int + +func (t *Type) Align() int { + return rtype_Align(t) +} + +//go:linkname rtype_FieldAlign reflect.(*rtype).FieldAlign +//go:noescape +func rtype_FieldAlign(*Type) int + +func (t *Type) FieldAlign() int { + return rtype_FieldAlign(t) +} + +//go:linkname rtype_Method reflect.(*rtype).Method +//go:noescape +func rtype_Method(*Type, int) reflect.Method + +func (t *Type) Method(a0 int) reflect.Method { + return rtype_Method(t, a0) +} + +//go:linkname rtype_MethodByName reflect.(*rtype).MethodByName +//go:noescape +func rtype_MethodByName(*Type, string) (reflect.Method, bool) + +func (t *Type) MethodByName(a0 string) (reflect.Method, bool) { + return rtype_MethodByName(t, a0) +} + +//go:linkname rtype_NumMethod reflect.(*rtype).NumMethod +//go:noescape +func rtype_NumMethod(*Type) int + +func (t *Type) NumMethod() int { + return rtype_NumMethod(t) +} + +//go:linkname rtype_Name reflect.(*rtype).Name +//go:noescape +func rtype_Name(*Type) string + +func (t *Type) Name() string { + return rtype_Name(t) +} + +//go:linkname rtype_PkgPath reflect.(*rtype).PkgPath +//go:noescape +func rtype_PkgPath(*Type) string + +func (t *Type) PkgPath() string { + return rtype_PkgPath(t) +} + +//go:linkname rtype_Size reflect.(*rtype).Size +//go:noescape +func rtype_Size(*Type) uintptr + +func (t *Type) Size() uintptr { + return rtype_Size(t) +} + +//go:linkname rtype_String reflect.(*rtype).String +//go:noescape +func rtype_String(*Type) string + +func (t *Type) String() string { + return rtype_String(t) +} + +//go:linkname rtype_Kind reflect.(*rtype).Kind +//go:noescape +func rtype_Kind(*Type) reflect.Kind + +func (t *Type) Kind() reflect.Kind { + return rtype_Kind(t) +} + +//go:linkname rtype_Implements reflect.(*rtype).Implements +//go:noescape +func rtype_Implements(*Type, reflect.Type) bool + +func (t *Type) Implements(u reflect.Type) bool { + return rtype_Implements(t, u) +} + +//go:linkname rtype_AssignableTo reflect.(*rtype).AssignableTo +//go:noescape +func rtype_AssignableTo(*Type, reflect.Type) bool + +func (t *Type) AssignableTo(u reflect.Type) bool { + return rtype_AssignableTo(t, u) +} + +//go:linkname rtype_ConvertibleTo reflect.(*rtype).ConvertibleTo +//go:noescape +func rtype_ConvertibleTo(*Type, reflect.Type) bool + +func (t *Type) ConvertibleTo(u reflect.Type) bool { + return rtype_ConvertibleTo(t, u) +} + +//go:linkname rtype_Comparable reflect.(*rtype).Comparable +//go:noescape +func rtype_Comparable(*Type) bool + +func (t *Type) Comparable() bool { + return rtype_Comparable(t) +} + +//go:linkname rtype_Bits reflect.(*rtype).Bits +//go:noescape +func rtype_Bits(*Type) int + +func (t *Type) Bits() int { + return rtype_Bits(t) +} + +//go:linkname rtype_ChanDir reflect.(*rtype).ChanDir +//go:noescape +func rtype_ChanDir(*Type) reflect.ChanDir + +func (t *Type) ChanDir() reflect.ChanDir { + return rtype_ChanDir(t) +} + +//go:linkname rtype_IsVariadic reflect.(*rtype).IsVariadic +//go:noescape +func rtype_IsVariadic(*Type) bool + +func (t *Type) IsVariadic() bool { + return rtype_IsVariadic(t) +} + +//go:linkname rtype_Elem reflect.(*rtype).Elem +//go:noescape +func rtype_Elem(*Type) reflect.Type + +func (t *Type) Elem() *Type { + return Type2RType(rtype_Elem(t)) +} + +//go:linkname rtype_Field reflect.(*rtype).Field +//go:noescape +func rtype_Field(*Type, int) reflect.StructField + +func (t *Type) Field(i int) reflect.StructField { + return rtype_Field(t, i) +} + +//go:linkname rtype_FieldByIndex reflect.(*rtype).FieldByIndex +//go:noescape +func rtype_FieldByIndex(*Type, []int) reflect.StructField + +func (t *Type) FieldByIndex(index []int) reflect.StructField { + return rtype_FieldByIndex(t, index) +} + +//go:linkname rtype_FieldByName reflect.(*rtype).FieldByName +//go:noescape +func rtype_FieldByName(*Type, string) (reflect.StructField, bool) + +func (t *Type) FieldByName(name string) (reflect.StructField, bool) { + return rtype_FieldByName(t, name) +} + +//go:linkname rtype_FieldByNameFunc reflect.(*rtype).FieldByNameFunc +//go:noescape +func rtype_FieldByNameFunc(*Type, func(string) bool) (reflect.StructField, bool) + +func (t *Type) FieldByNameFunc(match func(string) bool) (reflect.StructField, bool) { + return rtype_FieldByNameFunc(t, match) +} + +//go:linkname rtype_In reflect.(*rtype).In +//go:noescape +func rtype_In(*Type, int) reflect.Type + +func (t *Type) In(i int) reflect.Type { + return rtype_In(t, i) +} + +//go:linkname rtype_Key reflect.(*rtype).Key +//go:noescape +func rtype_Key(*Type) reflect.Type + +func (t *Type) Key() *Type { + return Type2RType(rtype_Key(t)) +} + +//go:linkname rtype_Len reflect.(*rtype).Len +//go:noescape +func rtype_Len(*Type) int + +func (t *Type) Len() int { + return rtype_Len(t) +} + +//go:linkname rtype_NumField reflect.(*rtype).NumField +//go:noescape +func rtype_NumField(*Type) int + +func (t *Type) NumField() int { + return rtype_NumField(t) +} + +//go:linkname rtype_NumIn reflect.(*rtype).NumIn +//go:noescape +func rtype_NumIn(*Type) int + +func (t *Type) NumIn() int { + return rtype_NumIn(t) +} + +//go:linkname rtype_NumOut reflect.(*rtype).NumOut +//go:noescape +func rtype_NumOut(*Type) int + +func (t *Type) NumOut() int { + return rtype_NumOut(t) +} + +//go:linkname rtype_Out reflect.(*rtype).Out +//go:noescape +func rtype_Out(*Type, int) reflect.Type + +//go:linkname PtrTo reflect.(*rtype).ptrTo +//go:noescape +func PtrTo(*Type) *Type + +func (t *Type) Out(i int) reflect.Type { + return rtype_Out(t, i) +} + +//go:linkname IfaceIndir reflect.ifaceIndir +//go:noescape +func IfaceIndir(*Type) bool + +//go:linkname RType2Type reflect.toType +//go:noescape +func RType2Type(t *Type) reflect.Type + +//go:nolint structcheck +type emptyInterface struct { + _ *Type + ptr unsafe.Pointer +} + +func Type2RType(t reflect.Type) *Type { + return (*Type)(((*emptyInterface)(unsafe.Pointer(&t))).ptr) +} diff --git a/vendor/github.com/goccy/go-json/internal/runtime/struct_field.go b/vendor/github.com/goccy/go-json/internal/runtime/struct_field.go new file mode 100644 index 000000000..baab0c597 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/runtime/struct_field.go @@ -0,0 +1,91 @@ +package runtime + +import ( + "reflect" + "strings" + "unicode" +) + +func getTag(field reflect.StructField) string { + return field.Tag.Get("json") +} + +func IsIgnoredStructField(field reflect.StructField) bool { + if field.PkgPath != "" { + if field.Anonymous { + t := field.Type + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + if t.Kind() != reflect.Struct { + return true + } + } else { + // private field + return true + } + } + tag := getTag(field) + return tag == "-" +} + +type StructTag struct { + Key string + IsTaggedKey bool + IsOmitEmpty bool + IsString bool + Field reflect.StructField +} + +type StructTags []*StructTag + +func (t StructTags) ExistsKey(key string) bool { + for _, tt := range t { + if tt.Key == key { + return true + } + } + return false +} + +func isValidTag(s string) bool { + if s == "" { + return false + } + for _, c := range s { + switch { + case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): + // Backslash and quote chars are reserved, but + // otherwise any punctuation chars are allowed + // in a tag name. + case !unicode.IsLetter(c) && !unicode.IsDigit(c): + return false + } + } + return true +} + +func StructTagFromField(field reflect.StructField) *StructTag { + keyName := field.Name + tag := getTag(field) + st := &StructTag{Field: field} + opts := strings.Split(tag, ",") + if len(opts) > 0 { + if opts[0] != "" && isValidTag(opts[0]) { + keyName = opts[0] + st.IsTaggedKey = true + } + } + st.Key = keyName + if len(opts) > 1 { + for _, opt := range opts[1:] { + switch opt { + case "omitempty": + st.IsOmitEmpty = true + case "string": + st.IsString = true + } + } + } + return st +} diff --git a/vendor/github.com/goccy/go-json/internal/runtime/type.go b/vendor/github.com/goccy/go-json/internal/runtime/type.go new file mode 100644 index 000000000..0167cd2c0 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/runtime/type.go @@ -0,0 +1,100 @@ +package runtime + +import ( + "reflect" + "unsafe" +) + +type SliceHeader struct { + Data unsafe.Pointer + Len int + Cap int +} + +const ( + maxAcceptableTypeAddrRange = 1024 * 1024 * 2 // 2 Mib +) + +type TypeAddr struct { + BaseTypeAddr uintptr + MaxTypeAddr uintptr + AddrRange uintptr + AddrShift uintptr +} + +var ( + typeAddr *TypeAddr + alreadyAnalyzed bool +) + +//go:linkname typelinks reflect.typelinks +func typelinks() ([]unsafe.Pointer, [][]int32) + +//go:linkname rtypeOff reflect.rtypeOff +func rtypeOff(unsafe.Pointer, int32) unsafe.Pointer + +func AnalyzeTypeAddr() *TypeAddr { + defer func() { + alreadyAnalyzed = true + }() + if alreadyAnalyzed { + return typeAddr + } + sections, offsets := typelinks() + if len(sections) != 1 { + return nil + } + if len(offsets) != 1 { + return nil + } + section := sections[0] + offset := offsets[0] + var ( + min uintptr = uintptr(^uint(0)) + max uintptr = 0 + isAligned64 = true + isAligned32 = true + ) + for i := 0; i < len(offset); i++ { + typ := (*Type)(rtypeOff(section, offset[i])) + addr := uintptr(unsafe.Pointer(typ)) + if min > addr { + min = addr + } + if max < addr { + max = addr + } + if typ.Kind() == reflect.Ptr { + addr = uintptr(unsafe.Pointer(typ.Elem())) + if min > addr { + min = addr + } + if max < addr { + max = addr + } + } + isAligned64 = isAligned64 && (addr-min)&63 == 0 + isAligned32 = isAligned32 && (addr-min)&31 == 0 + } + addrRange := max - min + if addrRange == 0 { + return nil + } + var addrShift uintptr + if isAligned64 { + addrShift = 6 + } else if isAligned32 { + addrShift = 5 + } + cacheSize := addrRange >> addrShift + if cacheSize > maxAcceptableTypeAddrRange { + return nil + } + typeAddr = &TypeAddr{ + BaseTypeAddr: min, + MaxTypeAddr: max, + AddrRange: addrRange, + AddrShift: addrShift, + } + return typeAddr +} diff --git a/vendor/github.com/goccy/go-json/json.go b/vendor/github.com/goccy/go-json/json.go new file mode 100644 index 000000000..413cb20bf --- /dev/null +++ b/vendor/github.com/goccy/go-json/json.go @@ -0,0 +1,371 @@ +package json + +import ( + "bytes" + "context" + "encoding/json" + + "github.com/goccy/go-json/internal/encoder" +) + +// Marshaler is the interface implemented by types that +// can marshal themselves into valid JSON. +type Marshaler interface { + MarshalJSON() ([]byte, error) +} + +// MarshalerContext is the interface implemented by types that +// can marshal themselves into valid JSON with context.Context. +type MarshalerContext interface { + MarshalJSON(context.Context) ([]byte, error) +} + +// 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. +// +// By convention, to approximate the behavior of Unmarshal itself, +// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op. +type Unmarshaler interface { + UnmarshalJSON([]byte) error +} + +// UnmarshalerContext is the interface implemented by types +// that can unmarshal with context.Context a JSON description of themselves. +type UnmarshalerContext interface { + UnmarshalJSON(context.Context, []byte) error +} + +// Marshal returns the JSON encoding of v. +// +// Marshal traverses the value v recursively. +// If an encountered value implements the Marshaler interface +// and is not a nil pointer, Marshal calls its MarshalJSON method +// to produce JSON. If no MarshalJSON method is present but the +// value implements encoding.TextMarshaler instead, Marshal calls +// its MarshalText method and encodes the result as a JSON string. +// The nil pointer exception is not strictly necessary +// but mimics a similar, necessary exception in the behavior of +// UnmarshalJSON. +// +// Otherwise, Marshal uses the following type-dependent default encodings: +// +// Boolean values encode as JSON booleans. +// +// Floating point, integer, and Number values encode as JSON numbers. +// +// String values encode as JSON strings coerced to valid UTF-8, +// replacing invalid bytes with the Unicode replacement rune. +// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" +// to keep some browsers from misinterpreting JSON output as HTML. +// Ampersand "&" is also escaped to "\u0026" for the same reason. +// This escaping can be disabled using an Encoder that had SetEscapeHTML(false) +// called on it. +// +// Array and slice values encode as JSON arrays, except that +// []byte encodes as a base64-encoded string, and a nil slice +// encodes as the null JSON value. +// +// Struct values encode as JSON objects. +// Each exported struct field becomes a member of the object, using the +// field name as the object key, unless the field is omitted for one of the +// reasons given below. +// +// The encoding of each struct field can be customized by the format string +// stored under the "json" key in the struct field's tag. +// The format string gives the name of the field, possibly followed by a +// comma-separated list of options. The name may be empty in order to +// specify options without overriding the default field name. +// +// The "omitempty" option specifies that the field should be omitted +// from the encoding if the field has an empty value, defined as +// false, 0, a nil pointer, a nil interface value, and any empty array, +// slice, map, or string. +// +// As a special case, if the field tag is "-", the field is always omitted. +// Note that a field with name "-" can still be generated using the tag "-,". +// +// Examples of struct field tags and their meanings: +// +// // Field appears in JSON as key "myName". +// Field int `json:"myName"` +// +// // Field appears in JSON as key "myName" and +// // the field is omitted from the object if its value is empty, +// // as defined above. +// Field int `json:"myName,omitempty"` +// +// // Field appears in JSON as key "Field" (the default), but +// // the field is skipped if empty. +// // Note the leading comma. +// Field int `json:",omitempty"` +// +// // Field is ignored by this package. +// Field int `json:"-"` +// +// // Field appears in JSON as key "-". +// Field int `json:"-,"` +// +// The "string" option signals that a field is stored as JSON inside a +// JSON-encoded string. It applies only to fields of string, floating point, +// integer, or boolean types. This extra level of encoding is sometimes used +// when communicating with JavaScript programs: +// +// Int64String int64 `json:",string"` +// +// The key name will be used if it's a non-empty string consisting of +// only Unicode letters, digits, and ASCII punctuation except quotation +// marks, backslash, and comma. +// +// Anonymous struct fields are usually marshaled as if their inner exported fields +// were fields in the outer struct, subject to the usual Go visibility rules amended +// as described in the next paragraph. +// An anonymous struct field with a name given in its JSON tag is treated as +// having that name, rather than being anonymous. +// An anonymous struct field of interface type is treated the same as having +// that type as its name, rather than being anonymous. +// +// The Go visibility rules for struct fields are amended for JSON when +// deciding which field to marshal or unmarshal. If there are +// multiple fields at the same level, and that level is the least +// nested (and would therefore be the nesting level selected by the +// usual Go rules), the following extra rules apply: +// +// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, +// even if there are multiple untagged fields that would otherwise conflict. +// +// 2) If there is exactly one field (tagged or not according to the first rule), that is selected. +// +// 3) Otherwise there are multiple fields, and all are ignored; no error occurs. +// +// Handling of anonymous struct fields is new in Go 1.1. +// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of +// an anonymous struct field in both current and earlier versions, give the field +// a JSON tag of "-". +// +// Map values encode as JSON objects. The map's key type must either be a +// string, an integer type, or implement encoding.TextMarshaler. The map keys +// are sorted and used as JSON object keys by applying the following rules, +// subject to the UTF-8 coercion described for string values above: +// - string keys are used directly +// - encoding.TextMarshalers are marshaled +// - integer keys are converted to strings +// +// Pointer values encode as the value pointed to. +// A nil pointer encodes as the null JSON value. +// +// Interface values encode as the value contained in the interface. +// A nil interface value encodes as the null JSON value. +// +// Channel, complex, and function values cannot be encoded in JSON. +// Attempting to encode such a value causes Marshal to return +// an UnsupportedTypeError. +// +// JSON cannot represent cyclic data structures and Marshal does not +// handle them. Passing cyclic structures to Marshal will result in +// an infinite recursion. +// +func Marshal(v interface{}) ([]byte, error) { + return MarshalWithOption(v) +} + +// MarshalNoEscape returns the JSON encoding of v and doesn't escape v. +func MarshalNoEscape(v interface{}) ([]byte, error) { + return marshalNoEscape(v) +} + +// MarshalContext returns the JSON encoding of v with context.Context and EncodeOption. +func MarshalContext(ctx context.Context, v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) { + return marshalContext(ctx, v, optFuncs...) +} + +// MarshalWithOption returns the JSON encoding of v with EncodeOption. +func MarshalWithOption(v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) { + return marshal(v, optFuncs...) +} + +// MarshalIndent is like Marshal but applies Indent to format the output. +// Each JSON element in the output will begin on a new line beginning with prefix +// followed by one or more copies of indent according to the indentation nesting. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + return MarshalIndentWithOption(v, prefix, indent) +} + +// MarshalIndentWithOption is like Marshal but applies Indent to format the output with EncodeOption. +func MarshalIndentWithOption(v interface{}, prefix, indent string, optFuncs ...EncodeOptionFunc) ([]byte, error) { + return marshalIndent(v, prefix, indent, optFuncs...) +} + +// 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. +// +// To unmarshal JSON into a value implementing the Unmarshaler interface, +// Unmarshal calls that value's UnmarshalJSON method, including +// when the input is a JSON null. +// Otherwise, if the value implements encoding.TextUnmarshaler +// and the input is a JSON quoted string, Unmarshal calls that value's +// UnmarshalText method with the unquoted form of the string. +// +// 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 +// []interface{}, for JSON arrays +// map[string]interface{}, for JSON objects +// nil for JSON null +// +// To unmarshal a JSON array into a slice, Unmarshal resets the slice length +// to zero and then appends each element to the slice. +// As a special case, to unmarshal an empty JSON array into a slice, +// Unmarshal replaces the slice with a new empty slice. +// +// To unmarshal a JSON array into a Go array, Unmarshal decodes +// JSON array elements into corresponding Go array elements. +// If the Go array is smaller than the JSON array, +// the additional JSON array elements are discarded. +// If the JSON array is smaller than the Go array, +// the additional Go array elements are set to zero values. +// +// To unmarshal a JSON object into a 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, implement json.Unmarshaler, or +// implement encoding.TextUnmarshaler. +// +// 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 interface{}) error { + return unmarshal(data, v) +} + +// UnmarshalContext parses the JSON-encoded data and stores the result +// in the value pointed to by v. If you implement the UnmarshalerContext interface, +// call it with ctx as an argument. +func UnmarshalContext(ctx context.Context, data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { + return unmarshalContext(ctx, data, v) +} + +func UnmarshalWithOption(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { + return unmarshal(data, v, optFuncs...) +} + +func UnmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { + return unmarshalNoEscape(data, v, optFuncs...) +} + +// A Token holds a value of one of these types: +// +// Delim, for the four JSON delimiters [ ] { } +// bool, for JSON booleans +// float64, for JSON numbers +// Number, for JSON numbers +// string, for JSON string literals +// nil, for JSON null +// +type Token = json.Token + +// A Number represents a JSON number literal. +type Number = json.Number + +// RawMessage is a raw encoded JSON value. +// It implements Marshaler and Unmarshaler and can +// be used to delay JSON decoding or precompute a JSON encoding. +type RawMessage = json.RawMessage + +// A Delim is a JSON array or object delimiter, one of [ ] { or }. +type Delim = json.Delim + +// Compact appends to dst the JSON-encoded src with +// insignificant space characters elided. +func Compact(dst *bytes.Buffer, src []byte) error { + return encoder.Compact(dst, src, false) +} + +// Indent appends to dst an indented form of the JSON-encoded src. +// Each element in a JSON object or array begins on a new, +// indented line beginning with prefix followed by one or more +// copies of indent according to the indentation nesting. +// The data appended to dst does not begin with the prefix nor +// any indentation, to make it easier to embed inside other formatted JSON data. +// Although leading space characters (space, tab, carriage return, newline) +// at the beginning of src are dropped, trailing space characters +// at the end of src are preserved and copied to dst. +// For example, if src has no trailing spaces, neither will dst; +// if src ends in a trailing newline, so will dst. +func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error { + return encoder.Indent(dst, src, prefix, indent) +} + +// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 +// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 +// so that the JSON will be safe to embed inside HTML